1414import logging
1515import random
1616from concurrent .futures import ThreadPoolExecutor
17- from pathlib import Path
18- from typing import Any , AsyncGenerator , AsyncIterator , Callable , Dict , Mapping , Optional , Type , TypeVar , Union , cast
17+ from typing import Any , AsyncGenerator , AsyncIterator , Callable , Mapping , Optional , Type , TypeVar , Union , cast
1918
20- import yaml
2119from opentelemetry import trace as trace_api
2220from pydantic import BaseModel
2321
@@ -200,8 +198,8 @@ def __init__(
200198 Union [Callable [..., Any ], _DefaultCallbackHandlerSentinel ]
201199 ] = _DEFAULT_CALLBACK_HANDLER ,
202200 conversation_manager : Optional [ConversationManager ] = None ,
203- record_direct_tool_call : Optional [ bool ] = None ,
204- load_tools_from_directory : Optional [ bool ] = None ,
201+ record_direct_tool_call : bool = True ,
202+ load_tools_from_directory : bool = False ,
205203 trace_attributes : Optional [Mapping [str , AttributeValue ]] = None ,
206204 * ,
207205 agent_id : Optional [str ] = None ,
@@ -210,7 +208,6 @@ def __init__(
210208 state : Optional [Union [AgentState , dict ]] = None ,
211209 hooks : Optional [list [HookProvider ]] = None ,
212210 session_manager : Optional [SessionManager ] = None ,
213- config : Optional [Union [str , Path , Dict [str , Any ]]] = None ,
214211 ):
215212 """Initialize the Agent with the specified configuration.
216213
@@ -237,11 +234,9 @@ def __init__(
237234 conversation_manager: Manager for conversation history and context window.
238235 Defaults to strands.agent.conversation_manager.SlidingWindowConversationManager if None.
239236 record_direct_tool_call: Whether to record direct tool calls in message history.
240- Defaults to True. When using config, this parameter only overrides the config value
241- if explicitly provided.
237+ Defaults to True.
242238 load_tools_from_directory: Whether to load and automatically reload tools in the `./tools/` directory.
243- Defaults to False. When using config, this parameter only overrides the config value
244- if explicitly provided.
239+ Defaults to False.
245240 trace_attributes: Custom trace attributes to apply to the agent's trace span.
246241 agent_id: Optional ID for the agent, useful for session management and multi-agent scenarios.
247242 Defaults to "default".
@@ -255,108 +250,10 @@ def __init__(
255250 Defaults to None.
256251 session_manager: Manager for handling agent sessions including conversation history and state.
257252 If provided, enables session-based persistence and state management.
258- config: Configuration for initializing the agent from a file or dictionary.
259- Can be specified as:
260-
261- - String: Path to a YAML (.yaml, .yml) or JSON (.json) configuration file
262- - Path: Path object to a YAML (.yaml, .yml) or JSON (.json) configuration file
263- - Dict: Configuration dictionary with agent parameters
264-
265- When provided, the agent is initialized using the AgentConfigLoader with the specified
266- configuration. The config takes precedence over individual parameters, but individual
267- parameters can override config values when both are provided.
268253
269254 Raises:
270255 ValueError: If agent id contains path separators.
271- FileNotFoundError: If config is a string/Path that doesn't exist.
272- ValueError: If config file format is not supported (must be .yaml, .yml, or .json).
273256 """
274- # Handle config-based initialization
275- if config is not None :
276- # Load configuration from file or use provided dict
277- config_dict = self ._load_config (config )
278-
279- # Handle both direct agent config and config with 'agent' key
280- if "agent" in config_dict :
281- agent_config = config_dict ["agent" ]
282- else :
283- agent_config = config_dict
284-
285- # Import AgentConfigLoader here to avoid circular imports
286- from ..experimental .config_loader .agent import AgentConfigLoader
287-
288- # Create agent from config and return early
289- config_loader = AgentConfigLoader ()
290- configured_agent = config_loader .load_agent (agent_config )
291-
292- # There is an odd mypy type discrepancy in this file for some reason
293- # There is a mismatch between src.strands.* and strands.*
294- # type/ignore annotations allow type checking to pass
295-
296- # Override config values with any explicitly provided parameters
297- if model is not None :
298- configured_agent .model = (
299- BedrockModel () if not model else BedrockModel (model_id = model ) if isinstance (model , str ) else model # type: ignore
300- )
301- if messages is not None :
302- configured_agent .messages = messages
303- if tools is not None :
304- # Need to reinitialize tool registry with new tools
305- configured_agent .tool_registry = ToolRegistry () # type: ignore
306- configured_agent .tool_registry .process_tools (tools )
307- configured_agent .tool_registry .initialize_tools (load_tools_from_directory ) # type: ignore
308- if system_prompt is not None :
309- configured_agent .system_prompt = system_prompt
310- if not isinstance (callback_handler , _DefaultCallbackHandlerSentinel ):
311- if callback_handler is None :
312- configured_agent .callback_handler = null_callback_handler
313- else :
314- configured_agent .callback_handler = callback_handler
315- if conversation_manager is not None :
316- configured_agent .conversation_manager = conversation_manager # type: ignore
317- if trace_attributes is not None :
318- configured_agent .trace_attributes = {}
319- for k , v in trace_attributes .items ():
320- if isinstance (v , (str , int , float , bool )) or (
321- isinstance (v , list ) and all (isinstance (x , (str , int , float , bool )) for x in v )
322- ):
323- configured_agent .trace_attributes [k ] = v
324- if agent_id is not None :
325- configured_agent .agent_id = _identifier .validate (agent_id , _identifier .Identifier .AGENT )
326- if name is not None :
327- configured_agent .name = name
328- if description is not None :
329- configured_agent .description = description
330- if state is not None :
331- if isinstance (state , dict ):
332- configured_agent .state = AgentState (state ) # type: ignore
333- elif isinstance (state , AgentState ):
334- configured_agent .state = state # type: ignore
335- else :
336- raise ValueError ("state must be an AgentState object or a dict" )
337- if hooks is not None :
338- for hook in hooks :
339- configured_agent .hooks .add_hook (hook ) # type: ignore
340- if session_manager is not None :
341- configured_agent ._session_manager = session_manager # type: ignore
342- configured_agent .hooks .add_hook (session_manager ) # type: ignore
343-
344- # Override record_direct_tool_call and load_tools_from_directory only if explicitly provided
345- if record_direct_tool_call is not None :
346- configured_agent .record_direct_tool_call = record_direct_tool_call
347- if load_tools_from_directory is not None :
348- configured_agent .load_tools_from_directory = load_tools_from_directory
349- if load_tools_from_directory :
350- if hasattr (configured_agent , "tool_watcher" ):
351- configured_agent .tool_watcher = ToolWatcher (tool_registry = configured_agent .tool_registry ) # type: ignore
352- else :
353- configured_agent .tool_watcher = ToolWatcher (tool_registry = configured_agent .tool_registry ) # type: ignore
354-
355- # Copy all attributes from configured agent to self
356- self .__dict__ .update (configured_agent .__dict__ )
357- return
358-
359- # Standard initialization when no config is provided
360257 self .model = BedrockModel () if not model else BedrockModel (model_id = model ) if isinstance (model , str ) else model
361258 self .messages = messages if messages is not None else []
362259
@@ -387,8 +284,8 @@ def __init__(
387284 ):
388285 self .trace_attributes [k ] = v
389286
390- self .record_direct_tool_call = record_direct_tool_call if record_direct_tool_call is not None else True
391- self .load_tools_from_directory = load_tools_from_directory if load_tools_from_directory is not None else False
287+ self .record_direct_tool_call = record_direct_tool_call
288+ self .load_tools_from_directory = load_tools_from_directory
392289
393290 self .tool_registry = ToolRegistry ()
394291
@@ -432,42 +329,6 @@ def __init__(
432329 self .hooks .add_hook (hook )
433330 self .hooks .invoke_callbacks (AgentInitializedEvent (agent = self ))
434331
435- def _load_config (self , config : Union [str , Path , Dict [str , Any ]]) -> Dict [str , Any ]:
436- """Load configuration from file or return provided dictionary.
437-
438- Args:
439- config: Either a file path (string or Path), or configuration dictionary
440-
441- Returns:
442- Configuration dictionary
443-
444- Raises:
445- FileNotFoundError: If config is a string/Path that doesn't exist
446- ValueError: If config file format is not supported
447- """
448- if isinstance (config , dict ):
449- return config
450-
451- # Handle both str and Path objects
452- if isinstance (config , (str , Path )):
453- config_path = Path (config )
454-
455- if not config_path .exists ():
456- raise FileNotFoundError (f"Configuration file not found: { config } " )
457-
458- suffix = config_path .suffix .lower ()
459-
460- if suffix in [".yaml" , ".yml" ]:
461- with open (config_path , "r" , encoding = "utf-8" ) as f :
462- return dict [str , Any ](yaml .safe_load (f ))
463- elif suffix == ".json" :
464- with open (config_path , "r" , encoding = "utf-8" ) as f :
465- return dict [str , Any ](json .load (f ))
466- else :
467- raise ValueError (f"Unsupported config file format: { suffix } . Supported formats: .yaml, .yml, .json" )
468-
469- raise ValueError (f"Config must be a string (file path), Path object, or dictionary, got: { type (config )} " )
470-
471332 @property
472333 def tool (self ) -> ToolCaller :
473334 """Call tool as a function.
@@ -859,4 +720,4 @@ def _end_agent_trace_span(
859720 def _append_message (self , message : Message ) -> None :
860721 """Appends a message to the agent's list of messages and invokes the callbacks for the MessageCreatedEvent."""
861722 self .messages .append (message )
862- self .hooks .invoke_callbacks (MessageAddedEvent (agent = self , message = message ))
723+ self .hooks .invoke_callbacks (MessageAddedEvent (agent = self , message = message ))
0 commit comments