-
Notifications
You must be signed in to change notification settings - Fork 132
feat: Add include_default_tools option to control built-in tools #1594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This change adds a new 'disable_default_tools' field to AgentBase that allows users to exclude specific default tools (finish, think) from being automatically added to the agent. This enables users to: - Disable the think tool if not needed - Disable the finish tool to provide a custom implementation - Replace built-in tools with custom versions that have different behavior or output formats The implementation: - Adds 'disable_default_tools: list[str]' field to AgentBase - Updates _initialize() to skip tools whose names are in the list - Adds '_initialized' flag to properly track initialization state (needed because empty tools dict is now valid) - Adds tests for disabling individual tools, all tools, and replacing with custom implementations Fixes #1592 Co-authored-by: openhands <[email protected]>
neubig
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks pretty good to me, but do we want to use a list of classes as opposed to a list of strings? That might be more typo-proof.
|
@OpenHands can you address this comment #1594 (review)? |
|
Uh oh! There was an unexpected error starting the job :( |
|
@OpenHands can you address this comment #1594 (review)? |
|
I'm on it! xingyaoww can track my progress at all-hands.dev |
Changed disable_default_tools from list[str] to list[type[ToolDefinition]] to make the API more typo-proof. Users now pass tool classes directly (e.g., [ThinkTool, FinishTool]) instead of string names. Added serializer/validator to handle JSON serialization by converting classes to/from their class names. Co-authored-by: openhands <[email protected]>
|
I've addressed the PR review comment from @neubig requesting to use tool classes instead of strings for Changes Made
Usage Examples (Updated)from openhands.sdk.tool import ThinkTool, FinishTool
# Disable the think tool
agent = Agent(llm=llm, tools=[], disable_default_tools=[ThinkTool])
# Disable the finish tool and provide a custom implementation
agent = Agent(
llm=llm,
tools=[Tool(name="custom_finish")],
disable_default_tools=[FinishTool],
)
# Disable all default tools
agent = Agent(llm=llm, tools=[], disable_default_tools=[FinishTool, ThinkTool])The changes have been pushed to the PR branch: #1594 |
Change the field from disable_default_tools to include_default_tools with BUILT_IN_TOOLS as the default value. This maintains backward compatibility since the default behavior includes all default tools. Users can now: - Set include_default_tools=[] to disable all default tools - Set include_default_tools=[FinishTool] to only include FinishTool - Set include_default_tools=[ThinkTool] to only include ThinkTool Co-authored-by: openhands <[email protected]>
|
@OpenHands please fix the failing actions on PR #1594 at branch |
|
I'm on it! xingyaoww can track my progress at all-hands.dev |
…neration The previous implementation used list[type[ToolDefinition]] which caused FastAPI's OpenAPI schema generation to fail because Pydantic couldn't generate a schema for the ToolExecutor type (used in ToolDefinition). This change: - Changes the field type from list[type[ToolDefinition]] to list[str] - Stores tool class names as strings instead of class references - Keeps backward compatibility by accepting both strings and tool classes in the validator (tool classes are converted to their names) - Resolves tool class names to actual classes at initialization time The API remains backward compatible - users can still pass tool classes like [FinishTool, ThinkTool] and they will be converted to strings. Co-authored-by: openhands <[email protected]>
Update tests to use string tool names instead of tool classes to match the new type annotation. The validator still accepts both strings and tool classes for backward compatibility, but the type annotation is list[str] to ensure proper OpenAPI schema generation. Co-authored-by: openhands <[email protected]>
Replace ToolDefinition.resolve_kind() with an explicit BUILT_IN_TOOL_CLASSES mapping for deserializing include_default_tools. This is more reliable as resolve_kind() depends on subclass discovery which may fail if classes haven't been imported. Also add comprehensive tests for include_default_tools serialization and deserialization to ensure round-trip works correctly. Co-authored-by: openhands <[email protected]>
|
Looks like there are a few issues preventing this PR from being merged!
If you'd like me to help, just leave a comment, like Feel free to include any additional details that might help me get this PR into a better state. You can manage your notification settings |
AgentBase is a frozen Pydantic model, so agent_context cannot be set after the agent is created. This fix passes agent_context directly to the Agent constructor instead of setting it as an attribute. Co-authored-by: openhands <[email protected]>
Move BUILT_IN_TOOL_CLASSES definition to the same location as BUILT_IN_TOOLS in openhands/sdk/tool/builtins/__init__.py and generate it dynamically using a dict comprehension instead of hardcoding the mapping. Co-authored-by: openhands <[email protected]>
Remove the field validator for include_default_tools to simplify the code. Validation of tool names is already done at initialization time in _initialize(). Also remove the related tests that depended on the validator behavior. Co-authored-by: openhands <[email protected]>
Summary
This PR adds a new
include_default_toolsfield toAgentBasethat allows users to control which default tools (FinishTool,ThinkTool) are automatically added to the agent.This addresses the issue where users want to create custom versions of the finish or think tools but cannot exclude the built-in versions.
Changes
New field
include_default_tools: list[str]- A list of default tool class names to include. By default, includes all built-in tools (["FinishTool", "ThinkTool"]). Set to an empty list to disable all default tools, or provide a subset to include only specific ones.Updated
_initialize()method - Now only adds tools that are in theinclude_default_toolslist.Added
_initializedflag - Needed to properly track initialization state since an empty tools dict is now valid when all default tools are disabled.Dynamic
BUILT_IN_TOOL_CLASSESgeneration - The mapping of tool class names to classes is now generated dynamically fromBUILT_IN_TOOLSinopenhands/sdk/tool/builtins/__init__.py, making it easier to add new built-in tools in the future.Usage Examples
Fixes #1592
Checklist
Agent Server images for this PR
• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server
Variants & Base Images
eclipse-temurin:17-jdknikolaik/python-nodejs:python3.12-nodejs22golang:1.21-bookwormPull (multi-arch manifest)
# Each variant is a multi-arch manifest supporting both amd64 and arm64 docker pull ghcr.io/openhands/agent-server:7f46298-pythonRun
All tags pushed for this build
About Multi-Architecture Support
7f46298-python) is a multi-arch manifest supporting both amd64 and arm647f46298-python-amd64) are also available if needed