make browser download timeout configurable for blocks and tasks (#3619)

This commit is contained in:
Jonathan Dobson
2025-10-06 11:09:20 -04:00
committed by GitHub
parent a9d0280336
commit a758b03861
11 changed files with 60 additions and 5 deletions

View File

@@ -18,6 +18,7 @@ from playwright.async_api import Page
from skyvern import analytics
from skyvern.config import settings
from skyvern.constants import (
BROWSER_DOWNLOAD_TIMEOUT,
BROWSER_DOWNLOADING_SUFFIX,
DEFAULT_MAX_SCREENSHOT_SCROLLS,
GET_DOWNLOADED_FILES_TIMEOUT,
@@ -199,6 +200,7 @@ class ForgeAgent:
extra_http_headers=workflow_run.extra_http_headers,
browser_address=workflow_run.browser_address,
browser_session_id=workflow_run.browser_session_id,
download_timeout=task_block.download_timeout,
)
LOG.info(
"Created a new task for workflow run",
@@ -217,6 +219,7 @@ class ForgeAgent:
organization_id=task.organization_id,
status=TaskStatus.running,
)
step = await app.DATABASE.create_step(
task.task_id,
order=0,
@@ -500,7 +503,10 @@ class ForgeAgent:
step_id=step.step_id,
)
try:
await wait_for_download_finished(downloading_files=downloading_files)
await wait_for_download_finished(
downloading_files=downloading_files,
timeout=task_block.download_timeout or BROWSER_DOWNLOAD_TIMEOUT,
)
except DownloadFileMaxWaitingTime as e:
LOG.warning(
"There're several long-time downloading files, these files might be broken",

View File

@@ -172,6 +172,7 @@ class AgentDB:
extra_http_headers: dict[str, str] | None = None,
browser_session_id: str | None = None,
browser_address: str | None = None,
download_timeout: float | None = None,
) -> Task:
try:
async with self.Session() as session:
@@ -203,6 +204,7 @@ class AgentDB:
extra_http_headers=extra_http_headers,
browser_session_id=browser_session_id,
browser_address=browser_address,
download_timeout=download_timeout,
)
session.add(new_task)
await session.commit()

View File

@@ -109,6 +109,7 @@ class TaskModel(Base):
)
model = Column(JSON, nullable=True)
browser_address = Column(String, nullable=True)
download_timeout = Column(Numeric, nullable=True)
class StepModel(Base):

View File

@@ -158,6 +158,7 @@ def convert_to_task(task_obj: TaskModel, debug_enabled: bool = False, workflow_p
max_screenshot_scrolls=task_obj.max_screenshot_scrolling_times,
browser_session_id=task_obj.browser_session_id,
browser_address=task_obj.browser_address,
download_timeout=task_obj.download_timeout,
)
return task

View File

@@ -113,6 +113,11 @@ class TaskBase(BaseModel):
description="The CDP address for the task.",
examples=["http://127.0.0.1:9222", "ws://127.0.0.1:9222/devtools/browser/1234567890"],
)
download_timeout: float | None = Field(
default=None,
description="The maximum time to wait for downloads to complete, in minutes. If not set, defaults to BROWSER_DOWNLOAD_TIMEOUT minutes.",
examples=[15.0],
)
class TaskRequest(TaskBase):

View File

@@ -422,6 +422,7 @@ class BaseTaskBlock(Block):
cache_actions: bool = False
complete_verification: bool = True
include_action_history_in_verification: bool = False
download_timeout: float | None = None # minutes
def get_all_parameters(
self,
@@ -631,6 +632,7 @@ class BaseTaskBlock(Block):
failure_reason=str(e),
)
raise e
try:
# add screenshot artifact for the first task
screenshot = await browser_state.take_fullpage_screenshot(

View File

@@ -2490,6 +2490,7 @@ class WorkflowService:
cache_actions=block_yaml.cache_actions,
complete_on_download=True,
complete_verification=True,
download_timeout=block_yaml.download_timeout,
)
elif block_yaml.block_type == BlockType.TaskV2:
return TaskV2Block(