4444logger = logging .getLogger (__name__ )
4545
4646
47+ # Sentinel class and object to distinguish between explicit None and default parameter value
48+ class _DefaultCallbackHandlerSentinel :
49+ """Sentinel class to distinguish between explicit None and default parameter value."""
50+
51+ pass
52+
53+
54+ _DEFAULT_CALLBACK_HANDLER = _DefaultCallbackHandlerSentinel ()
55+
56+
4757class Agent :
4858 """Core Agent interface.
4959
@@ -70,7 +80,7 @@ def __init__(self, agent: "Agent") -> None:
7080 # agent tools and thus break their execution.
7181 self ._agent = agent
7282
73- def __getattr__ (self , name : str ) -> Callable :
83+ def __getattr__ (self , name : str ) -> Callable [..., Any ] :
7484 """Call tool as a function.
7585
7686 This method enables the method-style interface (e.g., `agent.tool.tool_name(param="value")`).
@@ -177,7 +187,9 @@ def __init__(
177187 messages : Optional [Messages ] = None ,
178188 tools : Optional [List [Union [str , Dict [str , str ], Any ]]] = None ,
179189 system_prompt : Optional [str ] = None ,
180- callback_handler : Optional [Callable ] = PrintingCallbackHandler (),
190+ callback_handler : Optional [
191+ Union [Callable [..., Any ], _DefaultCallbackHandlerSentinel ]
192+ ] = _DEFAULT_CALLBACK_HANDLER ,
181193 conversation_manager : Optional [ConversationManager ] = None ,
182194 max_parallel_tools : int = os .cpu_count () or 1 ,
183195 record_direct_tool_call : bool = True ,
@@ -204,7 +216,8 @@ def __init__(
204216 system_prompt: System prompt to guide model behavior.
205217 If None, the model will behave according to its default settings.
206218 callback_handler: Callback for processing events as they happen during agent execution.
207- Defaults to strands.handlers.PrintingCallbackHandler if None.
219+ If not provided (using the default), a new PrintingCallbackHandler instance is created.
220+ If explicitly set to None, null_callback_handler is used.
208221 conversation_manager: Manager for conversation history and context window.
209222 Defaults to strands.agent.conversation_manager.SlidingWindowConversationManager if None.
210223 max_parallel_tools: Maximum number of tools to run in parallel when the model returns multiple tool calls.
@@ -222,7 +235,17 @@ def __init__(
222235 self .messages = messages if messages is not None else []
223236
224237 self .system_prompt = system_prompt
225- self .callback_handler = callback_handler or null_callback_handler
238+
239+ # If not provided, create a new PrintingCallbackHandler instance
240+ # If explicitly set to None, use null_callback_handler
241+ # Otherwise use the passed callback_handler
242+ self .callback_handler : Union [Callable [..., Any ], PrintingCallbackHandler ]
243+ if isinstance (callback_handler , _DefaultCallbackHandlerSentinel ):
244+ self .callback_handler = PrintingCallbackHandler ()
245+ elif callback_handler is None :
246+ self .callback_handler = null_callback_handler
247+ else :
248+ self .callback_handler = callback_handler
226249
227250 self .conversation_manager = conversation_manager if conversation_manager else SlidingWindowConversationManager ()
228251
@@ -415,7 +438,7 @@ def target_callback() -> None:
415438 thread .join ()
416439
417440 def _run_loop (
418- self , prompt : str , kwargs : Any , supplementary_callback_handler : Optional [Callable ] = None
441+ self , prompt : str , kwargs : Dict [ str , Any ] , supplementary_callback_handler : Optional [Callable [..., Any ] ] = None
419442 ) -> AgentResult :
420443 """Execute the agent's event loop with the given prompt and parameters."""
421444 try :
@@ -441,7 +464,7 @@ def _run_loop(
441464 finally :
442465 self .conversation_manager .apply_management (self )
443466
444- def _execute_event_loop_cycle (self , callback_handler : Callable , kwargs : dict [str , Any ]) -> AgentResult :
467+ def _execute_event_loop_cycle (self , callback_handler : Callable [..., Any ], kwargs : Dict [str , Any ]) -> AgentResult :
445468 """Execute the event loop cycle with retry logic for context window limits.
446469
447470 This internal method handles the execution of the event loop cycle and implements
0 commit comments