Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pdm.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ dependencies = [
"requests>=2.32.3",
"Jinja2>=3.1.4",
"pydantic-settings>=2.7.0",
"tenacity>=9.0.0",
"tenacity>=9.1.2",
"python-dateutil>=2.9.0.post0",
"openai>=1.61.1",
"segment-analytics-python>=2.3.4",
Expand Down
21 changes: 18 additions & 3 deletions src/askui/models/askui/askui_computer_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
BetaToolResultBlockParam,
BetaToolUseBlockParam,
)
from tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential

from askui.models.askui.settings import AskUiComputerAgentSettings
from askui.reporting import Reporter
Expand Down Expand Up @@ -163,6 +164,13 @@
</IMPORTANT>""" # noqa: DTZ002, E501


def is_retryable_error(exception: BaseException) -> bool:
"""Check if the exception is a retryable error (status codes 429 or 529)."""
if isinstance(exception, httpx.HTTPStatusError):
return exception.response.status_code in (429, 529)
return False


class AskUiComputerAgent:
def __init__(
self,
Expand All @@ -184,6 +192,12 @@ def __init__(
},
)

@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=30, max=240),
retry=retry_if_exception(is_retryable_error),
reraise=True,
)
def step(self, messages: list[BetaMessageParam]) -> list[BetaMessageParam]:
if self._settings.only_n_most_recent_images:
self._maybe_filter_to_n_most_recent_images(
Expand All @@ -203,14 +217,15 @@ def step(self, messages: list[BetaMessageParam]) -> list[BetaMessageParam]:
}
logger.debug(request_body)
response = self._client.post(
"/act/inference", json=request_body, timeout=120.0
"/act/inference", json=request_body, timeout=300.0
)
response.raise_for_status()
response_data = response.json()
beta_message = BetaMessage.model_validate(response_data)
except Exception as e: # noqa: BLE001
logger.error(e)
return messages
if is_retryable_error(e):
logger.debug(e)
raise

response_params = self._response_to_params(beta_message)
new_message: BetaMessageParam = {
Expand Down