44
44
logger = logging .getLogger (__name__ )
45
45
46
46
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
+
47
57
class Agent :
48
58
"""Core Agent interface.
49
59
@@ -70,7 +80,7 @@ def __init__(self, agent: "Agent") -> None:
70
80
# agent tools and thus break their execution.
71
81
self ._agent = agent
72
82
73
- def __getattr__ (self , name : str ) -> Callable :
83
+ def __getattr__ (self , name : str ) -> Callable [..., Any ] :
74
84
"""Call tool as a function.
75
85
76
86
This method enables the method-style interface (e.g., `agent.tool.tool_name(param="value")`).
@@ -177,7 +187,9 @@ def __init__(
177
187
messages : Optional [Messages ] = None ,
178
188
tools : Optional [List [Union [str , Dict [str , str ], Any ]]] = None ,
179
189
system_prompt : Optional [str ] = None ,
180
- callback_handler : Optional [Callable ] = PrintingCallbackHandler (),
190
+ callback_handler : Optional [
191
+ Union [Callable [..., Any ], _DefaultCallbackHandlerSentinel ]
192
+ ] = _DEFAULT_CALLBACK_HANDLER ,
181
193
conversation_manager : Optional [ConversationManager ] = None ,
182
194
max_parallel_tools : int = os .cpu_count () or 1 ,
183
195
record_direct_tool_call : bool = True ,
@@ -204,7 +216,8 @@ def __init__(
204
216
system_prompt: System prompt to guide model behavior.
205
217
If None, the model will behave according to its default settings.
206
218
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.
208
221
conversation_manager: Manager for conversation history and context window.
209
222
Defaults to strands.agent.conversation_manager.SlidingWindowConversationManager if None.
210
223
max_parallel_tools: Maximum number of tools to run in parallel when the model returns multiple tool calls.
@@ -222,7 +235,17 @@ def __init__(
222
235
self .messages = messages if messages is not None else []
223
236
224
237
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
226
249
227
250
self .conversation_manager = conversation_manager if conversation_manager else SlidingWindowConversationManager ()
228
251
@@ -415,7 +438,7 @@ def target_callback() -> None:
415
438
thread .join ()
416
439
417
440
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
419
442
) -> AgentResult :
420
443
"""Execute the agent's event loop with the given prompt and parameters."""
421
444
try :
@@ -441,7 +464,7 @@ def _run_loop(
441
464
finally :
442
465
self .conversation_manager .apply_management (self )
443
466
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 :
445
468
"""Execute the event loop cycle with retry logic for context window limits.
446
469
447
470
This internal method handles the execution of the event loop cycle and implements
0 commit comments