generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 420
Add agent configuration support with JSON/dict configs and tool name resolution #865
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
Closed
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
97672ba
Add agent configuration support with JSON/dict configs and tool name …
mrlee-amazon d3e71f7
feat: implement experimental AgentConfig and ToolPool with natural API
mrlee-amazon ba645f1
feat: implement experimental AgentConfig and ToolBox with comprehensi…
mrlee-amazon 5eb5076
refactor: reorder toolbox creation logic and add default tools test
mrlee-amazon 891e125
Update src/strands/experimental/agent_config.py
mr-lee 4b065ff
feat: Use ToolRegistry in AgentConfig
Unshure 0a02c24
Update .gitignore
Unshure File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,4 +11,5 @@ __pycache__* | |
.vscode | ||
dist | ||
repl_state | ||
.kiro | ||
.kiro | ||
uv.lock |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
"""Experimental agent configuration with enhanced instantiation patterns.""" | ||
|
||
import importlib | ||
import json | ||
from typing import TYPE_CHECKING, Any | ||
|
||
from ..tools.registry import ToolRegistry | ||
|
||
if TYPE_CHECKING: | ||
# Import here to avoid circular imports: | ||
# experimental/agent_config.py -> agent.agent -> event_loop.event_loop -> | ||
# experimental.hooks -> experimental.__init__.py -> AgentConfig | ||
from ..agent.agent import Agent | ||
|
||
# File prefix for configuration file paths | ||
FILE_PREFIX = "file://" | ||
|
||
# Minimum viable list of tools to enable agent building | ||
# This list is experimental and will be revisited as tools evolve | ||
DEFAULT_TOOLS = ["file_read", "editor", "http_request", "shell", "use_agent"] | ||
|
||
|
||
class AgentConfig: | ||
"""Agent configuration with to_agent() method and ToolRegistry integration. | ||
|
||
Example config.json: | ||
{ | ||
"model": "anthropic.claude-3-5-sonnet-20241022-v2:0", | ||
"prompt": "You are a helpful assistant", | ||
"tools": ["file_read", "editor"] | ||
} | ||
""" | ||
|
||
def __init__( | ||
self, | ||
config_source: str | dict[str, Any], | ||
tool_registry: ToolRegistry | None = None, | ||
raise_exception_on_missing_tool: bool = True, | ||
): | ||
"""Initialize AgentConfig from file path or dictionary. | ||
|
||
Args: | ||
config_source: Path to JSON config file (must start with 'file://') or config dictionary | ||
tool_registry: Optional ToolRegistry to select tools from when 'tools' is specified in config | ||
raise_exception_on_missing_tool: If False, skip missing tools instead of raising ImportError | ||
|
||
Example: | ||
# Dictionary config | ||
config = AgentConfig({ | ||
"model": "anthropic.claude-3-5-sonnet-20241022-v2:0", | ||
"prompt": "You are a helpful assistant", | ||
"tools": ["file_read", "editor"] | ||
}) | ||
|
||
# File config | ||
config = AgentConfig("file://config.json") | ||
""" | ||
if isinstance(config_source, str): | ||
# Require file:// prefix for file paths | ||
if not config_source.startswith(FILE_PREFIX): | ||
raise ValueError(f"File paths must be prefixed with '{FILE_PREFIX}'") | ||
|
||
# Remove file:// prefix and load from file | ||
file_path = config_source.removeprefix(FILE_PREFIX) | ||
with open(file_path, "r") as f: | ||
config_data = json.load(f) | ||
else: | ||
# Use dictionary directly | ||
config_data = config_source | ||
|
||
self.model = config_data.get("model") | ||
self.system_prompt = config_data.get("prompt") # Only accept 'prompt' key | ||
self._raise_exception_on_missing_tool = raise_exception_on_missing_tool | ||
|
||
# Handle tool selection from ToolRegistry | ||
if tool_registry is not None: | ||
self._tool_registry = tool_registry | ||
else: | ||
# Create default ToolRegistry with strands_tools | ||
self._tool_registry = self._create_default_tool_registry() | ||
|
||
# Process tools configuration if provided | ||
config_tools = config_data.get("tools") | ||
|
||
# Track configured tools separately from full tool pool | ||
self._configured_tools = [] | ||
|
||
# Apply tool selection if specified | ||
if config_tools is not None: | ||
# Validate all tool names exist in the ToolRegistry | ||
available_tools = self._tool_registry.registry.keys() | ||
|
||
missing_tools = set(config_tools).difference(available_tools) | ||
if missing_tools and self._raise_exception_on_missing_tool: | ||
raise ValueError( | ||
f"Tool(s) '{missing_tools}' not found in ToolRegistry. Available tools: {available_tools}" | ||
) | ||
|
||
for tool_name in config_tools: | ||
if tool_name in self._tool_registry.registry: | ||
tool = self._tool_registry.registry[tool_name] | ||
self._configured_tools.append(tool) | ||
# If no tools specified in config, use no tools (empty list) | ||
|
||
def _create_default_tool_registry(self) -> ToolRegistry: | ||
"""Create default ToolRegistry with strands_tools.""" | ||
tool_registry = ToolRegistry() | ||
|
||
try: | ||
tool_modules = [importlib.import_module(f"strands_tools.{tool}") for tool in DEFAULT_TOOLS] | ||
tool_registry.process_tools(tool_modules) | ||
except ImportError as e: | ||
if self._raise_exception_on_missing_tool: | ||
raise ImportError( | ||
"strands_tools is not available and no ToolRegistry was specified. " | ||
"Either install strands_tools with 'pip install strands-agents-tools' " | ||
"or provide your own ToolRegistry with your own tools." | ||
) from e | ||
|
||
return tool_registry | ||
|
||
@property | ||
def tool_registry(self) -> ToolRegistry: | ||
"""Get the full ToolRegistry (superset of all available tools). | ||
|
||
Returns: | ||
ToolRegistry instance containing all available tools | ||
""" | ||
return self._tool_registry | ||
|
||
@property | ||
def configured_tools(self) -> list: | ||
"""Get the configured tools (subset selected for this agent). | ||
|
||
Returns: | ||
List of tools configured for this agent | ||
""" | ||
return self._configured_tools | ||
|
||
def to_agent(self, **kwargs: Any) -> "Agent": | ||
"""Create an Agent instance from this configuration. | ||
|
||
Args: | ||
**kwargs: Additional parameters to override config values. | ||
Supports all Agent constructor parameters. | ||
|
||
Returns: | ||
Configured Agent instance | ||
|
||
Example: | ||
# Using default tools from strands_tools | ||
config = AgentConfig({ | ||
"model": "anthropic.claude-3-5-sonnet-20241022-v2:0", | ||
"prompt": "You are a helpful assistant", | ||
"tools": ["file_read"] | ||
}) | ||
agent = config.to_agent() | ||
response = agent("Read the contents of README.md") | ||
|
||
# Using custom ToolRegistry | ||
from strands import tool | ||
|
||
@tool | ||
def custom_tool(input: str) -> str: | ||
return f"Custom: {input}" | ||
|
||
custom_tool_registry = ToolRegistry() | ||
custom_tool_registry.process_tools([custom_tool]) | ||
config = AgentConfig({ | ||
"model": "anthropic.claude-3-5-sonnet-20241022-v2:0", | ||
"prompt": "You are a custom assistant", | ||
"tools": ["custom_tool"] | ||
}, tool_registry=custom_tool_registry) | ||
agent = config.to_agent() | ||
""" | ||
# Import at runtime since TYPE_CHECKING import is not available during execution | ||
from ..agent.agent import Agent | ||
mr-lee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Start with config values | ||
agent_params = {} | ||
|
||
if self.model is not None: | ||
agent_params["model"] = self.model | ||
if self.system_prompt is not None: | ||
agent_params["system_prompt"] = self.system_prompt | ||
|
||
# Use configured tools (subset of tool pool) | ||
agent_params["tools"] = self._configured_tools | ||
|
||
# Override with any other provided kwargs | ||
agent_params.update(kwargs) | ||
|
||
return Agent(**agent_params) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.