Better handling of LLM request failures

This commit is contained in:
Ahmed Allam
2025-09-10 15:39:01 -07:00
parent 914b981072
commit 9a9a7268cd
10 changed files with 84 additions and 25 deletions
+34 -7
View File
@@ -13,7 +13,7 @@ from jinja2 import (
select_autoescape,
)
from strix.llm import LLM, LLMConfig
from strix.llm import LLM, LLMConfig, LLMRequestFailedError
from strix.llm.utils import clean_content
from strix.tools import process_tool_invocations
@@ -164,6 +164,10 @@ class BaseAgent(metaclass=AgentMeta):
await self._enter_waiting_state(tracer)
continue
if self.state.llm_failed:
await self._wait_for_input()
continue
self.state.increment_iteration()
try:
@@ -176,6 +180,13 @@ class BaseAgent(metaclass=AgentMeta):
await self._enter_waiting_state(tracer, error_occurred=False, was_cancelled=True)
continue
except LLMRequestFailedError as e:
self.state.add_error(f"LLM request failed: {e}")
self.state.enter_waiting_state(llm_failed=True)
if tracer:
tracer.update_agent_status(self.state.agent_id, "llm_failed")
continue
except (RuntimeError, ValueError, TypeError) as e:
if not await self._handle_iteration_error(e, tracer):
await self._enter_waiting_state(tracer, error_occurred=True)
@@ -327,7 +338,7 @@ class BaseAgent(metaclass=AgentMeta):
tracer.update_agent_status(self.state.agent_id, "error")
return True
def _check_agent_messages(self, state: AgentState) -> None:
def _check_agent_messages(self, state: AgentState) -> None: # noqa: PLR0912
try:
from strix.tools.agents_graph.agents_graph_actions import _agent_graph, _agent_messages
@@ -340,13 +351,29 @@ class BaseAgent(metaclass=AgentMeta):
has_new_messages = False
for message in messages:
if not message.get("read", False):
if state.is_waiting_for_input():
state.resume_from_waiting()
has_new_messages = True
sender_name = "Unknown Agent"
sender_id = message.get("from")
if state.is_waiting_for_input():
if state.llm_failed:
if sender_id == "user":
state.resume_from_waiting()
has_new_messages = True
from strix.cli.tracer import get_global_tracer
tracer = get_global_tracer()
if tracer:
tracer.update_agent_status(state.agent_id, "running")
else:
state.resume_from_waiting()
has_new_messages = True
from strix.cli.tracer import get_global_tracer
tracer = get_global_tracer()
if tracer:
tracer.update_agent_status(state.agent_id, "running")
if sender_id == "user":
sender_name = "User"
state.add_message("user", message.get("content", ""))
+4 -1
View File
@@ -23,6 +23,7 @@ class AgentState(BaseModel):
completed: bool = False
stop_requested: bool = False
waiting_for_input: bool = False
llm_failed: bool = False
final_result: dict[str, Any] | None = None
messages: list[dict[str, Any]] = Field(default_factory=list)
@@ -85,15 +86,17 @@ class AgentState(BaseModel):
def is_waiting_for_input(self) -> bool:
return self.waiting_for_input
def enter_waiting_state(self) -> None:
def enter_waiting_state(self, llm_failed: bool = False) -> None:
self.waiting_for_input = True
self.stop_requested = False
self.llm_failed = llm_failed
self.last_updated = datetime.now(UTC).isoformat()
def resume_from_waiting(self, new_task: str | None = None) -> None:
self.waiting_for_input = False
self.stop_requested = False
self.completed = False
self.llm_failed = False
if new_task:
self.task = new_task
self.last_updated = datetime.now(UTC).isoformat()