4545logger = logging .getLogger (__name__ )
4646
4747
48+ # Sentinel class and object to distinguish between explicit None and default parameter value
49+ class _DefaultCallbackHandlerSentinel :
50+ """Sentinel class to distinguish between explicit None and default parameter value."""
51+
52+ pass
53+
54+
55+ _DEFAULT_CALLBACK_HANDLER = _DefaultCallbackHandlerSentinel ()
56+
57+
4858class Agent :
4959 """Core Agent interface.
5060
@@ -71,7 +81,7 @@ def __init__(self, agent: "Agent") -> None:
7181 # agent tools and thus break their execution.
7282 self ._agent = agent
7383
74- def __getattr__ (self , name : str ) -> Callable :
84+ def __getattr__ (self , name : str ) -> Callable [..., Any ] :
7585 """Call tool as a function.
7686
7787 This method enables the method-style interface (e.g., `agent.tool.tool_name(param="value")`).
@@ -178,7 +188,9 @@ def __init__(
178188 messages : Optional [Messages ] = None ,
179189 tools : Optional [List [Union [str , Dict [str , str ], Any ]]] = None ,
180190 system_prompt : Optional [str ] = None ,
181- callback_handler : Optional [Callable ] = PrintingCallbackHandler (),
191+ callback_handler : Optional [
192+ Union [Callable [..., Any ], _DefaultCallbackHandlerSentinel ]
193+ ] = _DEFAULT_CALLBACK_HANDLER ,
182194 conversation_manager : Optional [ConversationManager ] = None ,
183195 tool_manager : Optional [ToolManager ] = None ,
184196 max_parallel_tools : int = os .cpu_count () or 1 ,
@@ -206,7 +218,8 @@ def __init__(
206218 system_prompt: System prompt to guide model behavior.
207219 If None, the model will behave according to its default settings.
208220 callback_handler: Callback for processing events as they happen during agent execution.
209- Defaults to strands.handlers.PrintingCallbackHandler if None.
221+ If not provided (using the default), a new PrintingCallbackHandler instance is created.
222+ If explicitly set to None, null_callback_handler is used.
210223 conversation_manager: Manager for conversation history and context window.
211224 Defaults to strands.agent.conversation_manager.SlidingWindowConversationManager if None.
212225 max_parallel_tools: Maximum number of tools to run in parallel when the model returns multiple tool calls.
@@ -224,7 +237,17 @@ def __init__(
224237 self .messages = messages if messages is not None else []
225238
226239 self .system_prompt = system_prompt
227- self .callback_handler = callback_handler or null_callback_handler
240+
241+ # If not provided, create a new PrintingCallbackHandler instance
242+ # If explicitly set to None, use null_callback_handler
243+ # Otherwise use the passed callback_handler
244+ self .callback_handler : Union [Callable [..., Any ], PrintingCallbackHandler ]
245+ if isinstance (callback_handler , _DefaultCallbackHandlerSentinel ):
246+ self .callback_handler = PrintingCallbackHandler ()
247+ elif callback_handler is None :
248+ self .callback_handler = null_callback_handler
249+ else :
250+ self .callback_handler = callback_handler
228251
229252 self .conversation_manager = conversation_manager if conversation_manager else SlidingWindowConversationManager ()
230253
@@ -455,7 +478,7 @@ def target_callback() -> None:
455478 thread .join ()
456479
457480 def _run_loop (
458- self , prompt : str , kwargs : Any , supplementary_callback_handler : Optional [Callable ] = None
481+ self , prompt : str , kwargs : Dict [ str , Any ] , supplementary_callback_handler : Optional [Callable [..., Any ] ] = None
459482 ) -> AgentResult :
460483 """Execute the agent's event loop with the given prompt and parameters."""
461484 try :
@@ -481,7 +504,7 @@ def _run_loop(
481504 finally :
482505 self .conversation_manager .apply_management (self )
483506
484- def _execute_event_loop_cycle (self , callback_handler : Callable , kwargs : dict [str , Any ]) -> AgentResult :
507+ def _execute_event_loop_cycle (self , callback_handler : Callable [..., Any ], kwargs : Dict [str , Any ]) -> AgentResult :
485508 """Execute the event loop cycle with retry logic for context window limits.
486509
487510 This internal method handles the execution of the event loop cycle and implements
0 commit comments