diff --git a/tests/integration/base.py b/tests/integration/base.py index c633d367af..3e9260b018 100644 --- a/tests/integration/base.py +++ b/tests/integration/base.py @@ -25,6 +25,7 @@ MessageEvent, ) from openhands.sdk.tool import Tool +from openhands.tools.preset.default import get_default_condenser, get_default_tools from tests.integration.early_stopper import EarlyStopperBase, EarlyStopResult @@ -195,19 +196,39 @@ def run_instruction(self) -> TestResult: self.teardown() @property - @abstractmethod + def enable_browser(self) -> bool: + """Whether to enable browser tools. Override to enable browser. + + Returns: + True to enable browser tools, False otherwise (default) + """ + return False + + @property def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - pass + """List of tools available to the agent. + + By default, uses the default preset tools from openhands.tools.preset.default. + Override this property to provide custom tools. + + Returns: + List of Tool instances + """ + return get_default_tools(enable_browser=self.enable_browser) @property def condenser(self) -> CondenserBase | None: - """Optional condenser for the agent. Override to provide a custom condenser. + """Optional condenser for the agent. + + By default, uses the default condenser from openhands.tools.preset.default. + Override to provide a custom condenser or return None to disable. Returns: - CondenserBase instance or None (default) + CondenserBase instance (default condenser) or None """ - return None + return get_default_condenser( + llm=self.llm.model_copy(update={"usage_id": "condenser"}) + ) @property def max_iteration_per_run(self) -> int: diff --git a/tests/integration/tests/b05_do_not_create_redundant_files.py b/tests/integration/tests/b05_do_not_create_redundant_files.py index 55b43c5e73..a7f1471a02 100644 --- a/tests/integration/tests/b05_do_not_create_redundant_files.py +++ b/tests/integration/tests/b05_do_not_create_redundant_files.py @@ -7,9 +7,6 @@ from textwrap import dedent from openhands.sdk import get_logger -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool from tests.integration.base import BaseIntegrationTest, SkipTest, TestResult from tests.integration.behavior_utils import ( get_conversation_summary, @@ -28,15 +25,12 @@ class NoRedundantFilesTest(BaseIntegrationTest): """Ensure the agent does not create any redundant files (e.g., .md files) - that are not asked by users when performing the task.""" + that are not asked by users when performing the task. - INSTRUCTION: str = INSTRUCTION + Uses the default agent preset (TerminalTool, FileEditorTool, TaskTrackerTool). + """ - @property - def tools(self) -> list[Tool]: - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [Tool(name="TerminalTool"), Tool(name="FileEditorTool")] + INSTRUCTION: str = INSTRUCTION def setup(self) -> None: # noqa: D401 """Set up a realistic codebase by cloning the lerobot repo.""" diff --git a/tests/integration/tests/t01_fix_simple_typo.py b/tests/integration/tests/t01_fix_simple_typo.py index 03f6ff1a00..9f7a9ff79d 100644 --- a/tests/integration/tests/t01_fix_simple_typo.py +++ b/tests/integration/tests/t01_fix_simple_typo.py @@ -3,9 +3,6 @@ import os from openhands.sdk import get_logger -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool from tests.integration.base import BaseIntegrationTest, TestResult @@ -26,7 +23,10 @@ class TypoFixTest(BaseIntegrationTest): - """Test that an agent can fix typos in a text file.""" + """Test that an agent can fix typos in a text file. + + Uses the default agent preset (TerminalTool, FileEditorTool, TaskTrackerTool). + """ INSTRUCTION: str = INSTRUCTION @@ -34,16 +34,6 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.document_path: str = os.path.join(self.workspace, "document.txt") - @property - def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [ - Tool(name="TerminalTool"), - Tool(name="FileEditorTool"), - ] - def setup(self) -> None: """Create a text file with typos for the agent to fix.""" # Create the test file with typos diff --git a/tests/integration/tests/t02_add_bash_hello.py b/tests/integration/tests/t02_add_bash_hello.py index 9c0ad9991c..fd9c90ce42 100644 --- a/tests/integration/tests/t02_add_bash_hello.py +++ b/tests/integration/tests/t02_add_bash_hello.py @@ -3,9 +3,6 @@ import os from openhands.sdk import get_logger -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool from tests.integration.base import BaseIntegrationTest, TestResult @@ -16,7 +13,10 @@ class BashHelloTest(BaseIntegrationTest): - """Test that an agent can write a shell script that prints 'hello'.""" + """Test that an agent can write a shell script that prints 'hello'. + + Uses the default agent preset (TerminalTool, FileEditorTool, TaskTrackerTool). + """ INSTRUCTION: str = INSTRUCTION @@ -24,16 +24,6 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.script_path: str = os.path.join(self.workspace, "shell", "hello.sh") - @property - def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [ - Tool(name="TerminalTool"), - Tool(name="FileEditorTool"), - ] - def setup(self) -> None: """Setup is not needed - agent will create directories as needed.""" diff --git a/tests/integration/tests/t03_jupyter_write_file.py b/tests/integration/tests/t03_jupyter_write_file.py index ca6e541efd..d144eba205 100644 --- a/tests/integration/tests/t03_jupyter_write_file.py +++ b/tests/integration/tests/t03_jupyter_write_file.py @@ -3,9 +3,6 @@ import os from openhands.sdk import get_logger -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool from tests.integration.base import BaseIntegrationTest, TestResult @@ -19,7 +16,10 @@ class JupyterWriteFileTest(BaseIntegrationTest): - """Test that an agent can use Jupyter IPython to write a text file.""" + """Test that an agent can use Jupyter IPython to write a text file. + + Uses the default agent preset (TerminalTool, FileEditorTool, TaskTrackerTool). + """ INSTRUCTION: str = INSTRUCTION @@ -27,16 +27,6 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.file_path: str = os.path.join(self.workspace, "test.txt") - @property - def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [ - Tool(name="TerminalTool"), - Tool(name="FileEditorTool"), - ] - def setup(self) -> None: """Setup is not needed - agent will create directories as needed.""" diff --git a/tests/integration/tests/t04_git_staging.py b/tests/integration/tests/t04_git_staging.py index 14c7fe4817..eddf999626 100644 --- a/tests/integration/tests/t04_git_staging.py +++ b/tests/integration/tests/t04_git_staging.py @@ -4,9 +4,6 @@ import subprocess from openhands.sdk import get_logger -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool from tests.integration.base import BaseIntegrationTest, TestResult @@ -19,19 +16,12 @@ class GitStagingTest(BaseIntegrationTest): - """Test that an agent can write a git commit message and commit changes.""" + """Test that an agent can write a git commit message and commit changes. - INSTRUCTION: str = INSTRUCTION + Uses the default agent preset (TerminalTool, FileEditorTool, TaskTrackerTool). + """ - @property - def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [ - Tool(name="TerminalTool"), - Tool(name="FileEditorTool"), - ] + INSTRUCTION: str = INSTRUCTION def setup(self) -> None: """Set up git repository with staged changes.""" diff --git a/tests/integration/tests/t05_simple_browsing.py b/tests/integration/tests/t05_simple_browsing.py index 09e5a5ec29..8f4b8f520a 100644 --- a/tests/integration/tests/t05_simple_browsing.py +++ b/tests/integration/tests/t05_simple_browsing.py @@ -7,9 +7,6 @@ from openhands.sdk import get_logger from openhands.sdk.conversation import get_agent_final_response -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool from tests.integration.base import BaseIntegrationTest, TestResult @@ -92,7 +89,10 @@ class SimpleBrowsingTest(BaseIntegrationTest): - """Test that an agent can browse a local web page and extract information.""" + """Test that an agent can browse a local web page and extract information. + + Uses the default agent preset with browser enabled. + """ INSTRUCTION: str = INSTRUCTION @@ -101,14 +101,9 @@ def __init__(self, *args, **kwargs): self.server_process: subprocess.Popen[bytes] | None = None @property - def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [ - Tool(name="TerminalTool"), - Tool(name="FileEditorTool"), - ] + def enable_browser(self) -> bool: + """Enable browser tools for this browsing test.""" + return True def setup(self) -> None: """Set up a local web server with the HTML file.""" diff --git a/tests/integration/tests/t06_github_pr_browsing.py b/tests/integration/tests/t06_github_pr_browsing.py index 9dccca8810..d5c5a533fe 100644 --- a/tests/integration/tests/t06_github_pr_browsing.py +++ b/tests/integration/tests/t06_github_pr_browsing.py @@ -2,9 +2,6 @@ from openhands.sdk import get_logger from openhands.sdk.conversation import get_agent_final_response -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool from tests.integration.base import BaseIntegrationTest, TestResult @@ -18,19 +15,17 @@ class GitHubPRBrowsingTest(BaseIntegrationTest): - """Test that an agent can browse a GitHub PR and extract information.""" + """Test that an agent can browse a GitHub PR and extract information. + + Uses the default agent preset with browser enabled. + """ INSTRUCTION: str = INSTRUCTION @property - def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [ - Tool(name="TerminalTool"), - Tool(name="FileEditorTool"), - ] + def enable_browser(self) -> bool: + """Enable browser tools for this browsing test.""" + return True def setup(self) -> None: """No special setup needed for GitHub PR browsing.""" diff --git a/tests/integration/tests/t07_interactive_commands.py b/tests/integration/tests/t07_interactive_commands.py index f8f1ee057e..1d28040631 100644 --- a/tests/integration/tests/t07_interactive_commands.py +++ b/tests/integration/tests/t07_interactive_commands.py @@ -4,9 +4,6 @@ import os from openhands.sdk import get_logger -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool from tests.integration.base import BaseIntegrationTest, TestResult @@ -32,7 +29,10 @@ class InteractiveCommandsTest(BaseIntegrationTest): - """Test that an agent can execute interactive Python scripts with input.""" + """Test that an agent can execute interactive Python scripts with input. + + Uses the default agent preset (TerminalTool, FileEditorTool, TaskTrackerTool). + """ INSTRUCTION: str = INSTRUCTION @@ -40,16 +40,6 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.script_path: str = os.path.join(self.workspace, "python_script.py") - @property - def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [ - Tool(name="TerminalTool"), - Tool(name="FileEditorTool"), - ] - def setup(self) -> None: """Set up the interactive Python script.""" diff --git a/tests/integration/tests/t08_image_file_viewing.py b/tests/integration/tests/t08_image_file_viewing.py index fb2cbddbf5..44f53ed9fd 100644 --- a/tests/integration/tests/t08_image_file_viewing.py +++ b/tests/integration/tests/t08_image_file_viewing.py @@ -5,9 +5,6 @@ from openhands.sdk import get_logger from openhands.sdk.conversation.response_utils import get_agent_final_response -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool from tests.integration.base import BaseIntegrationTest, SkipTest, TestResult @@ -23,7 +20,10 @@ class ImageFileViewingTest(BaseIntegrationTest): - """Test that an agent can view and analyze image files.""" + """Test that an agent can view and analyze image files. + + Uses the default agent preset (TerminalTool, FileEditorTool, TaskTrackerTool). + """ INSTRUCTION: str = INSTRUCTION @@ -38,16 +38,6 @@ def __init__(self, *args, **kwargs): "Please use a model that supports image input." ) - @property - def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [ - Tool(name="TerminalTool"), - Tool(name="FileEditorTool"), - ] - def setup(self) -> None: """Download the OpenHands logo for the agent to analyze.""" try: diff --git a/tests/integration/tests/t09_token_condenser.py b/tests/integration/tests/t09_token_condenser.py index dec8cf5715..bdee4cd1aa 100644 --- a/tests/integration/tests/t09_token_condenser.py +++ b/tests/integration/tests/t09_token_condenser.py @@ -9,8 +9,8 @@ from openhands.sdk import get_logger from openhands.sdk.context.condenser import LLMSummarizingCondenser from openhands.sdk.event.condenser import Condensation -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.terminal import TerminalTool +from openhands.sdk.tool import Tool +from openhands.tools.preset.default import get_default_tools from tests.integration.base import BaseIntegrationTest, SkipTest, TestResult @@ -34,7 +34,11 @@ class TokenCondenserTest(BaseIntegrationTest): - """Test that agent with token-based condenser triggers condensation.""" + """Test that agent with token-based condenser triggers condensation. + + Uses the default tools but with a custom condenser configuration + to test token-based condensation behavior. + """ INSTRUCTION: str = INSTRUCTION @@ -59,11 +63,8 @@ def __init__(self, *args, **kwargs): @property def tools(self) -> list[Tool]: - """List of tools available to the agent.""" - register_tool("TerminalTool", TerminalTool) - return [ - Tool(name="TerminalTool"), - ] + """Use default tools without browser for this test.""" + return get_default_tools(enable_browser=False) @property def condenser(self) -> LLMSummarizingCondenser: diff --git a/tests/integration/utils/behavior_helpers.py b/tests/integration/utils/behavior_helpers.py index 93a30ba946..d7343c4ca6 100644 --- a/tests/integration/utils/behavior_helpers.py +++ b/tests/integration/utils/behavior_helpers.py @@ -8,9 +8,8 @@ from typing import Any from openhands.sdk import get_logger -from openhands.sdk.tool import Tool, register_tool -from openhands.tools.file_editor import FileEditorTool -from openhands.tools.terminal import TerminalTool +from openhands.sdk.tool import Tool +from openhands.tools.preset.default import get_default_tools from tests.integration.base import BaseIntegrationTest, SkipTest from tests.integration.early_stopper import EarlyStopperBase @@ -84,10 +83,11 @@ def clone_pinned_software_agent_repo(workspace: str) -> Path: def default_behavior_tools() -> list[Tool]: - """Register and return the default tools for behavior tests.""" - register_tool("TerminalTool", TerminalTool) - register_tool("FileEditorTool", FileEditorTool) - return [Tool(name="TerminalTool"), Tool(name="FileEditorTool")] + """Register and return the default tools for behavior tests. + + Uses the default preset tools without browser support. + """ + return get_default_tools(enable_browser=False) ENVIRONMENT_TIPS_BODY = """\