3333 from .tracing import Tracer
3434
3535
36+ def _safe_tracer_call (
37+ tracer : Optional ["Tracer" ], method_name : str , verbose : bool , * args , ** kwargs
38+ ) -> None :
39+ """
40+ Safely call tracer method, catching and logging errors without breaking execution.
41+
42+ Args:
43+ tracer: Tracer instance or None
44+ method_name: Name of tracer method to call (e.g., "emit", "emit_error")
45+ verbose: Whether to print error messages
46+ *args: Positional arguments for the tracer method
47+ **kwargs: Keyword arguments for the tracer method
48+ """
49+ if not tracer :
50+ return
51+ try :
52+ method = getattr (tracer , method_name )
53+ if args and kwargs :
54+ method (* args , ** kwargs )
55+ elif args :
56+ method (* args )
57+ elif kwargs :
58+ method (** kwargs )
59+ else :
60+ method ()
61+ except Exception as tracer_error :
62+ # Tracer errors should not break agent execution
63+ if verbose :
64+ print (f"⚠️ Tracer error (non-fatal): { tracer_error } " )
65+
66+
3667class SentienceAgent (BaseAgent ):
3768 """
3869 High-level agent that combines Sentience SDK with any LLM provider.
@@ -159,7 +190,10 @@ def act( # noqa: C901
159190 # Emit step_start trace event if tracer is enabled
160191 if self .tracer :
161192 pre_url = self .browser .page .url if self .browser .page else None
162- self .tracer .emit_step_start (
193+ _safe_tracer_call (
194+ self .tracer ,
195+ "emit_step_start" ,
196+ self .verbose ,
163197 step_id = step_id ,
164198 step_index = self ._step_count ,
165199 goal = goal ,
@@ -228,7 +262,10 @@ def act( # noqa: C901
228262 if snap .screenshot_format :
229263 snapshot_data ["screenshot_format" ] = snap .screenshot_format
230264
231- self .tracer .emit (
265+ _safe_tracer_call (
266+ self .tracer ,
267+ "emit" ,
268+ self .verbose ,
232269 "snapshot" ,
233270 snapshot_data ,
234271 step_id = step_id ,
@@ -254,7 +291,10 @@ def act( # noqa: C901
254291
255292 # Emit LLM query trace event if tracer is enabled
256293 if self .tracer :
257- self .tracer .emit (
294+ _safe_tracer_call (
295+ self .tracer ,
296+ "emit" ,
297+ self .verbose ,
258298 "llm_query" ,
259299 {
260300 "prompt_tokens" : llm_response .prompt_tokens ,
@@ -315,7 +355,10 @@ def act( # noqa: C901
315355 for el in filtered_snap .elements [:50 ]
316356 ]
317357
318- self .tracer .emit (
358+ _safe_tracer_call (
359+ self .tracer ,
360+ "emit" ,
361+ self .verbose ,
319362 "action" ,
320363 {
321364 "action" : result .action ,
@@ -435,14 +478,28 @@ def act( # noqa: C901
435478 verify_data = verify_data ,
436479 )
437480
438- self .tracer .emit ("step_end" , step_end_data , step_id = step_id )
481+ _safe_tracer_call (
482+ self .tracer ,
483+ "emit" ,
484+ self .verbose ,
485+ "step_end" ,
486+ step_end_data ,
487+ step_id = step_id ,
488+ )
439489
440490 return result
441491
442492 except Exception as e :
443493 # Emit error trace event if tracer is enabled
444494 if self .tracer :
445- self .tracer .emit_error (step_id = step_id , error = str (e ), attempt = attempt )
495+ _safe_tracer_call (
496+ self .tracer ,
497+ "emit_error" ,
498+ self .verbose ,
499+ step_id = step_id ,
500+ error = str (e ),
501+ attempt = attempt ,
502+ )
446503
447504 if attempt < max_retries :
448505 if self .verbose :
@@ -668,7 +725,10 @@ async def act( # noqa: C901
668725 # Emit step_start trace event if tracer is enabled
669726 if self .tracer :
670727 pre_url = self .browser .page .url if self .browser .page else None
671- self .tracer .emit_step_start (
728+ _safe_tracer_call (
729+ self .tracer ,
730+ "emit_step_start" ,
731+ self .verbose ,
672732 step_id = step_id ,
673733 step_index = self ._step_count ,
674734 goal = goal ,
@@ -740,7 +800,10 @@ async def act( # noqa: C901
740800 if snap .screenshot_format :
741801 snapshot_data ["screenshot_format" ] = snap .screenshot_format
742802
743- self .tracer .emit (
803+ _safe_tracer_call (
804+ self .tracer ,
805+ "emit" ,
806+ self .verbose ,
744807 "snapshot" ,
745808 snapshot_data ,
746809 step_id = step_id ,
@@ -766,7 +829,10 @@ async def act( # noqa: C901
766829
767830 # Emit LLM query trace event if tracer is enabled
768831 if self .tracer :
769- self .tracer .emit (
832+ _safe_tracer_call (
833+ self .tracer ,
834+ "emit" ,
835+ self .verbose ,
770836 "llm_query" ,
771837 {
772838 "prompt_tokens" : llm_response .prompt_tokens ,
@@ -827,7 +893,10 @@ async def act( # noqa: C901
827893 for el in filtered_snap .elements [:50 ]
828894 ]
829895
830- self .tracer .emit (
896+ _safe_tracer_call (
897+ self .tracer ,
898+ "emit" ,
899+ self .verbose ,
831900 "action" ,
832901 {
833902 "action" : result .action ,
@@ -947,14 +1016,28 @@ async def act( # noqa: C901
9471016 verify_data = verify_data ,
9481017 )
9491018
950- self .tracer .emit ("step_end" , step_end_data , step_id = step_id )
1019+ _safe_tracer_call (
1020+ self .tracer ,
1021+ "emit" ,
1022+ self .verbose ,
1023+ "step_end" ,
1024+ step_end_data ,
1025+ step_id = step_id ,
1026+ )
9511027
9521028 return result
9531029
9541030 except Exception as e :
9551031 # Emit error trace event if tracer is enabled
9561032 if self .tracer :
957- self .tracer .emit_error (step_id = step_id , error = str (e ), attempt = attempt )
1033+ _safe_tracer_call (
1034+ self .tracer ,
1035+ "emit_error" ,
1036+ self .verbose ,
1037+ step_id = step_id ,
1038+ error = str (e ),
1039+ attempt = attempt ,
1040+ )
9581041
9591042 if attempt < max_retries :
9601043 if self .verbose :
0 commit comments