diff --git a/skyvern/forge/agent.py b/skyvern/forge/agent.py index 57718707..e7362afd 100644 --- a/skyvern/forge/agent.py +++ b/skyvern/forge/agent.py @@ -583,6 +583,7 @@ class ForgeAgent: actions=actions, action_results=[], actions_and_results=[], + step_exception=None, ) return step, detailed_agent_step_output @@ -776,13 +777,14 @@ class ForgeAgent: step_order=step.order, step_retry=step.retry_index, ) + detailed_agent_step_output.step_exception = "CancelledError" failed_step = await self.update_step( step=step, status=StepStatus.failed, output=detailed_agent_step_output.to_agent_step_output(), ) return failed_step, detailed_agent_step_output.get_clean_detailed_output() - except Exception: + except Exception as e: LOG.exception( "Unexpected exception in agent_step, marking step as failed", task_id=task.task_id, @@ -790,6 +792,7 @@ class ForgeAgent: step_order=step.order, step_retry=step.retry_index, ) + detailed_agent_step_output.step_exception = e.__class__.__name__ failed_step = await self.update_step( step=step, status=StepStatus.failed, @@ -882,6 +885,7 @@ class ForgeAgent: actions=None, action_results=None, actions_and_results=None, + step_exception=None, ) return step, browser_state, detailed_output diff --git a/skyvern/forge/sdk/api/llm/api_handler_factory.py b/skyvern/forge/sdk/api/llm/api_handler_factory.py index 494cdff2..92678db7 100644 --- a/skyvern/forge/sdk/api/llm/api_handler_factory.py +++ b/skyvern/forge/sdk/api/llm/api_handler_factory.py @@ -14,6 +14,7 @@ from skyvern.forge.sdk.api.llm.exceptions import ( DuplicateCustomLLMProviderError, InvalidLLMConfigError, LLMProviderError, + LLMProviderErrorRetryableTask, ) from skyvern.forge.sdk.api.llm.models import LLMAPIHandler, LLMConfig, LLMRouterConfig from skyvern.forge.sdk.api.llm.utils import llm_messages_builder, parse_api_response @@ -211,8 +212,8 @@ class LLMAPIHandlerFactory: **active_parameters, ) LOG.info("LLM API call successful", llm_key=llm_key, model=llm_config.model_name) - except openai.OpenAIError as e: - raise LLMProviderError(llm_key) from e + except litellm.exceptions.APIError as e: + raise LLMProviderErrorRetryableTask(llm_key) from e except CancelledError: t_llm_cancelled = time.perf_counter() LOG.error( diff --git a/skyvern/forge/sdk/api/llm/exceptions.py b/skyvern/forge/sdk/api/llm/exceptions.py index d67c6ad9..e4622004 100644 --- a/skyvern/forge/sdk/api/llm/exceptions.py +++ b/skyvern/forge/sdk/api/llm/exceptions.py @@ -40,6 +40,11 @@ class LLMProviderError(BaseLLMError): super().__init__(f"Error while using LLMProvider {llm_key}") +class LLMProviderErrorRetryableTask(LLMProviderError): + def __init__(self, llm_key: str) -> None: + super().__init__(f"Retryable error while using LLMProvider {llm_key}") + + class NoProviderEnabledError(BaseLLMError): def __init__(self) -> None: super().__init__( diff --git a/skyvern/webeye/actions/models.py b/skyvern/webeye/actions/models.py index 07665c63..6c21d068 100644 --- a/skyvern/webeye/actions/models.py +++ b/skyvern/webeye/actions/models.py @@ -39,6 +39,7 @@ class DetailedAgentStepOutput(BaseModel): actions: list[Action] | None action_results: list[ActionResult] | None actions_and_results: list[tuple[Action, list[ActionResult]]] | None + step_exception: str | None = None class Config: exclude = ["scraped_page", "extract_action_prompt"]