Skip to content

refactor: update tool registry interface #468

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

yakshpradippatel
Copy link
Member

@yakshpradippatel yakshpradippatel commented Jul 15, 2025

Description

New CRUD interface for Tool Registry for customers to directly use in their codebase

CREATE (create_tools):
agent.tool_registry.create_tools()
• ✅ Successfully creates new tools
• ✅ Returns list of created tool names
• ✅ Prevents duplicate tool creation with proper error handling

READ (read_tools):
agent.tool_registry.read_tools()
• ✅ Returns all tool specifications as a dictionary
• ✅ Provides access to tool metadata (name, description, schema)

UPDATE (update_tools):
agent.tool_registry.update_tools()
• ✅ Updates existing tools with new specifications
• ✅ Returns list of updated tool names
• ✅ Gracefully handles non-existent tools (returns empty list)

DELETE (delete_tools):
agent.tool_registry.delete_tools()
• ✅ Removes tools from registry
• ✅ Returns list of deleted tool names
• ✅ Raises ValueError for non-existent tools

Related Issues

https://github.com/strands-agents/private-sdk-python-staging/issues/26

Documentation PR

N/A

Type of Change

Breaking change to the ToolRegistry interface

Testing

  • I ran hatch run prepare

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • [] Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

except Exception as e:
logger.warning("tool_name=<%s> | failed to create function tool | %s", name, e)

return tools

def _update_tool_config(self, tool_config: Dict[str, Any], new_tool: NewToolDict) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need NewToolDict here? Can we just pass in ToolSpec which is already defined?

Comment on lines 61 to 62
providing a clean single interface for all tool registration needs. This replaces
the previous multi-step pattern for better separation of concerns.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets not mention what this replaces

- Dictionaries with name/path keys
- Instance of an AgentTool
load_tools_from_directory: Whether to automatically discover and load tools
from the ./tools/ directory.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Indents seem a little off here

logger.debug("tool_modules=<%s> | discovered", list(tool_modules.keys()))
return tool_modules

def _initialize_tools(self, load_tools_from_directory: bool = False) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename this to something like _load_tools_from_directory? And then instead of passing in the boolean, we conditionally call the method?

self.registry: Dict[str, AgentTool] = {}
self.dynamic_tools: Dict[str, AgentTool] = {}
self.tool_config: Optional[Dict[str, Any]] = None

def register_tools(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What methods in this class are meant to be public or private? If the only public method is register_tools, can we put an _ before the method names of the others?

Comment on lines 48 to 50
self.registry: Dict[str, AgentTool] = {}
self.dynamic_tools: Dict[str, AgentTool] = {}
self.tool_config: Optional[Dict[str, Any]] = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these attributes public or private? If private, and we put an _ prefix on them?

Comment on lines 106 to 110
except Exception:
# Restore original state on any failure (atomic operation)
self.registry = original_registry
self.dynamic_tools = original_dynamic_tools
raise
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to restore the tools here? If there is an unknown exception, it wont really matter if the tools are restored or not right? This should also simplify the logic in this function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy