agent: Retry on critical error
linuztx committed
Nov 18, 2025 at 18:49 UTC
dbebd4114505ec46e628595705e9d4c0888e65c3
2 files changed
+36
-3
agent.py
+35
-3
@@ -354,6 +354,7 @@ class Agent:
354
asyncio.run(self.call_extensions("agent_init"))
355
356
async def monologue(self):
357
+ error_retries = 0 # counter for critical error retries
358
while True:
359
try:
360
# loop data dictionary to pass to extensions
@@ -453,6 +454,7 @@ class Agent:
454
455
# exceptions inside message loop:
456
except InterventionException as e:
457
+ error_retries = 0 # reset retry counter on user intervention
458
pass # intervention message has been handled in handle_intervention(), proceed with conversation loop
459
except RepairableException as e:
460
# Forward repairable errors to the LLM, maybe it can fix them
@@ -462,8 +464,10 @@ class Agent:
464
PrintStyle(font_color="red", padding=True).print(msg["message"])
465
self.context.log.log(type="error", content=msg["message"])
466
except Exception as e:
465
- # Other exception kill the loop
466
- self.handle_critical_exception(e)
467
+ # Retry critical exceptions before failing
468
+ error_retries = await self.retry_critical_exception(
469
+ e, error_retries
470
+ )
471
472
finally:
473
# call message_loop_end extensions
@@ -473,9 +477,13 @@ class Agent:
477
478
# exceptions outside message loop:
479
except InterventionException as e:
480
+ error_retries = 0 # reset retry counter on user intervention
481
pass # just start over
482
except Exception as e:
478
- self.handle_critical_exception(e)
483
+ # Retry critical exceptions before failing
484
+ error_retries = await self.retry_critical_exception(
485
+ e, error_retries
486
+ )
487
finally:
488
self.context.streaming_agent = None # unset current streamer
489
# call monologue_end extensions
@@ -532,6 +540,30 @@ class Agent:
540
541
return full_prompt
542
543
+ async def retry_critical_exception(
544
+ self, e: Exception, error_retries: int, delay: int = 3, max_retries: int = 1
545
+ ) -> int:
546
+ if error_retries >= max_retries:
547
+ self.handle_critical_exception(e)
548
+
549
+ error_message = errors.format_error(e)
550
+
551
+ self.context.log.log(
552
+ type="warning", content="Critical error occurred, retrying..."
553
+ )
554
+ PrintStyle(font_color="orange", padding=True).print(
555
+ "Critical error occurred, retrying..."
556
+ )
557
+ await asyncio.sleep(delay)
558
+ agent_facing_error = self.read_prompt(
559
+ "fw.msg_critical_error.md", error_message=error_message
560
+ )
561
+ self.hist_add_warning(message=agent_facing_error)
562
+ PrintStyle(font_color="orange", padding=True).print(
563
+ agent_facing_error
564
+ )
565
+ return error_retries + 1
566
+
567
def handle_critical_exception(self, exception: Exception):
568
if isinstance(exception, HandledException):
569
raise exception # Re-raise the exception to kill the loop
prompts/fw.msg_critical_error.md
new
+1
@@ -0,0 +1 @@
1
+This error has occurred: {{error_message}}. Proceed with your original task if possible.
\ No newline at end of file