Skip to content

Implement dynamic tool registration for RemoteConversation #1128

@xingyaoww

Description

@xingyaoww

Problem

PR #1125 fixed an issue where creating a new conversation with planning agent tools would fail. However, the solution hardcodes tool registration on the server side by calling register_planning_tools() during server initialization in tool_router.py:

tool_router = APIRouter(prefix="/tools", tags=["Tools"])
register_default_tools(enable_browser=True)
register_planning_tools()  # Hardcoded registration

Why this is not ideal:

  • Server code needs to be modified every time we want to use a different set of tools
  • Not scalable - doesn't work for custom tool sets
  • Tight coupling between server and specific tool implementations
  • Clients cannot dynamically register their own tools

Proposed Solution

Instead of hardcoding tool registrations on the server side, we should implement automatic tool registration when creating a RemoteConversation:

  1. Client-side: When RemoteConversation.__init__() creates a new conversation, automatically detect all tools registered in the client's ToolRegistry using list_registered_tools()

  2. Send to server: Include the list of tool qualified names (qualnames) in the conversation creation payload

  3. Server-side: Dynamically register those tools on the server when the conversation is created

This approach provides:

  • ✅ Flexibility - clients can use any tool set without server changes
  • ✅ Scalability - works with custom tools automatically
  • ✅ Loose coupling - server doesn't need to know about specific tools in advance
  • ✅ Better developer experience - tools "just work" when registered on the client

Implementation Details

Client Side (RemoteConversation.__init__)

In openhands-sdk/openhands/sdk/conversation/impl/remote_conversation.py around line 454-476:

# Current code:
payload = {
    "agent": agent.model_dump(mode="json", context={"expose_secrets": True}),
    "initial_message": None,
    "max_iterations": max_iteration_per_run,
    "stuck_detection": stuck_detection,
    "workspace": LocalWorkspace(working_dir=self.workspace.working_dir).model_dump(),
}

# Proposed change:
from openhands.sdk.tool.registry import list_registered_tools

payload = {
    "agent": agent.model_dump(mode="json", context={"expose_secrets": True}),
    "initial_message": None,
    "max_iterations": max_iteration_per_run,
    "stuck_detection": stuck_detection,
    "workspace": LocalWorkspace(working_dir=self.workspace.working_dir).model_dump(),
    "registered_tools": list_registered_tools(),  # Add tool qualnames
}

Server Side

  1. API Model (openhands-agent-server/openhands/agent_server/models.py): Update the conversation creation request model to accept registered_tools field

  2. Conversation Router (openhands-agent-server/openhands/agent_server/conversation_router.py): Process the registered_tools list and dynamically register them

  3. Tool Registration: Need a mechanism to register tools by their qualified name (qualname) - may need to implement a tool import/registration utility

Additional Considerations

  • Tool Discovery: Need to ensure tools can be imported/registered by their qualname on the server side
  • Security: Validate that only allowed tools can be registered (prevent arbitrary code execution)
  • Backward Compatibility: Ensure this works with existing code that doesn't send tool lists
  • Error Handling: Handle cases where tools can't be registered on the server

Related Files

  • openhands-sdk/openhands/sdk/tool/registry.py - Tool registry with list_registered_tools()
  • openhands-sdk/openhands/sdk/conversation/impl/remote_conversation.py - RemoteConversation implementation
  • openhands-agent-server/openhands/agent_server/tool_router.py - Current hardcoded tool registration
  • openhands-agent-server/openhands/agent_server/conversation_router.py - Conversation creation endpoint
  • openhands-tools/openhands/tools/glob/definition.py - Example of tool auto-registration pattern

Acceptance Criteria

  • Client automatically sends list of registered tools when creating RemoteConversation
  • Server dynamically registers tools from the client's tool list
  • Planning agent tools work without hardcoded register_planning_tools() call
  • Custom tools can be used with RemoteConversation without server modifications
  • Backward compatibility maintained for existing code
  • Security considerations addressed (tool allowlist/validation)
  • Tests added for dynamic tool registration
  • Documentation updated

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions