Split block.py 6/8: extract single blocks → models/misc_blocks.py

Part 6/8. misc_blocks.py (TextPromptBlock, SendEmailBlock, WaitBlock, TaskV2Block,
HttpRequestBlock, PrintPageBlock, WorkflowTriggerBlock) imports Block/capture_block_download_baseline/
jinja_sandbox_env from block_base; schema/format helpers stay imported from block.py. capture
baseline call adapted to block_base signature. Block-type test patch targets repointed to misc_blocks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
AronPerez 2026-07-07 18:06:02 -05:00
parent ff933efca6
commit e5c35a48a4
No known key found for this signature in database
GPG key ID: 83807A86399C588E
13 changed files with 2317 additions and 2243 deletions

View file

@ -22,11 +22,11 @@ jobs:
# Provide the password for postgres
env:
POSTGRES_USER: skyvern
POSTGRES_DATABASE: skyvern
POSTGRES_DB: skyvern
POSTGRES_HOST_AUTH_METHOD: trust
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
--health-cmd "pg_isready -U skyvern -d skyvern" --health-interval 10s --health-timeout 5s --health-retries 5
ports:
# Maps tcp port 5432 on service container to the host
- 5432:5432

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,7 @@ BLOCK_MODEL_FILES = (
_MODELS_DIR / "block_base.py",
_MODELS_DIR / "code_block.py",
_MODELS_DIR / "parser_blocks.py",
_MODELS_DIR / "misc_blocks.py",
)
# Methods that make block-scoped LLM calls. Each must pass

View file

@ -1217,6 +1217,7 @@ async def test_register_pdf_uses_download_run_id_as_storage_key() -> None:
with (
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
patch("skyvern.forge.sdk.workflow.models.block_base.app", mock_app),
patch("skyvern.forge.sdk.workflow.models.misc_blocks.app", mock_app),
):
mock_app.STORAGE.save_downloaded_files = AsyncMock()
mock_app.STORAGE.get_downloaded_files = AsyncMock(return_value=[])
@ -1241,6 +1242,7 @@ async def test_register_pdf_defaults_to_workflow_run_id() -> None:
with (
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
patch("skyvern.forge.sdk.workflow.models.block_base.app", mock_app),
patch("skyvern.forge.sdk.workflow.models.misc_blocks.app", mock_app),
):
mock_app.STORAGE.save_downloaded_files = AsyncMock()
mock_app.STORAGE.get_downloaded_files = AsyncMock(return_value=[])
@ -1308,10 +1310,11 @@ async def test_print_page_block_threads_resolved_id_to_all_sinks(tmp_path) -> No
new_callable=AsyncMock,
return_value=(None, None),
),
patch("skyvern.forge.sdk.workflow.models.block.get_download_dir", side_effect=fake_get_download_dir),
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context.current", return_value=ctx),
patch("skyvern.forge.sdk.workflow.models.misc_blocks.get_download_dir", side_effect=fake_get_download_dir),
patch("skyvern.forge.sdk.workflow.models.misc_blocks.skyvern_context.current", return_value=ctx),
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
patch("skyvern.forge.sdk.workflow.models.block_base.app", mock_app),
patch("skyvern.forge.sdk.workflow.models.misc_blocks.app", mock_app),
):
mock_app.STORAGE.get_downloaded_files = AsyncMock(side_effect=fake_get_downloaded_files)
result = await block.execute(

View file

@ -8,9 +8,8 @@ import pytest
from skyvern.forge.sdk.schemas.tasks import TaskStatus
from skyvern.forge.sdk.workflow.context_manager import WorkflowRunContext
from skyvern.forge.sdk.workflow.exceptions import FailedToFormatJinjaStyleParameter
from skyvern.forge.sdk.workflow.models._jinja import _json_type_filter
from skyvern.forge.sdk.workflow.models._jinja import _JSON_TYPE_MARKER, _json_type_filter
from skyvern.forge.sdk.workflow.models.block import (
_JSON_TYPE_MARKER,
HttpRequestBlock,
jinja_sandbox_env,
)

View file

@ -9,8 +9,8 @@ import pytest
from skyvern.forge.sdk.core import skyvern_context
from skyvern.forge.sdk.core.skyvern_context import SkyvernContext
from skyvern.forge.sdk.schemas.files import FileInfo
from skyvern.forge.sdk.workflow.models import block as block_module
from skyvern.forge.sdk.workflow.models import block_base as block_base_module
from skyvern.forge.sdk.workflow.models import misc_blocks as block_module
from skyvern.forge.sdk.workflow.models.block import PrintPageBlock
from skyvern.forge.sdk.workflow.models.parameter import OutputParameter, ParameterType

View file

@ -11,7 +11,7 @@ import pytest
from skyvern.forge.sdk.core import skyvern_context
from skyvern.forge.sdk.core.skyvern_context import SkyvernContext
from skyvern.forge.sdk.schemas.task_v2 import TaskV2Status
from skyvern.forge.sdk.workflow.models import block as block_module
from skyvern.forge.sdk.workflow.models import misc_blocks as block_module
from skyvern.forge.sdk.workflow.models.block import TaskV2Block
from skyvern.forge.sdk.workflow.models.parameter import OutputParameter, ParameterType

View file

@ -11,8 +11,8 @@ from skyvern.forge.sdk.core.skyvern_context import SkyvernContext
from skyvern.forge.sdk.schemas.files import FileInfo
from skyvern.forge.sdk.schemas.task_v2 import TaskV2Status
from skyvern.forge.sdk.workflow.loop_download_filter import filter_downloaded_files_for_current_iteration
from skyvern.forge.sdk.workflow.models import block as block_module
from skyvern.forge.sdk.workflow.models import block_base as block_base_module
from skyvern.forge.sdk.workflow.models import misc_blocks as block_module
from skyvern.forge.sdk.workflow.models.block import TaskV2Block
from skyvern.forge.sdk.workflow.models.parameter import OutputParameter, ParameterType

View file

@ -6,7 +6,7 @@ import pytest
from jinja2 import StrictUndefined
from jinja2.sandbox import SandboxedEnvironment
import skyvern.forge.sdk.workflow.models.block as _block_mod
import skyvern.forge.sdk.workflow.models.misc_blocks as _block_mod
from skyvern.config import settings as base_settings
from skyvern.forge.prompts import prompt_engine
from skyvern.forge.sdk.api.llm.exceptions import InvalidLLMResponseFormat
@ -16,7 +16,7 @@ from skyvern.forge.sdk.workflow.models.block import TextPromptBlock
from skyvern.forge.sdk.workflow.models.parameter import OutputParameter, ParameterType
from skyvern.schemas.workflows import BlockStatus, TextPromptBlockYAML, WorkflowRequest
block_module = sys.modules["skyvern.forge.sdk.workflow.models.block"]
block_module = sys.modules["skyvern.forge.sdk.workflow.models.misc_blocks"]
def _make_workflow_run_context(values: dict | None = None) -> WorkflowRunContext:

View file

@ -250,7 +250,7 @@ def test_extraction_cache_key_changes_with_system_prompt() -> None:
def test_text_prompt_block_forwards_system_prompt(monkeypatch) -> None:
from skyvern.forge.sdk.workflow.models import block as block_module
from skyvern.forge.sdk.workflow.models import misc_blocks as block_module
captured: dict = {}

View file

@ -5,7 +5,7 @@ from unittest.mock import AsyncMock
import pytest
from skyvern.forge.sdk.workflow.context_manager import RANDOM_SECRET_ID_PREFIX, WorkflowRunContext
from skyvern.forge.sdk.workflow.models import block as block_module
from skyvern.forge.sdk.workflow.models import misc_blocks as block_module
from skyvern.forge.sdk.workflow.models.block import (
SECRET_RESPONSE_BODY_REDACTED,
HttpRequestBlock,

View file

@ -17,8 +17,8 @@ from skyvern.forge.sdk.workflow.exceptions import (
PayloadTemplateRenderError,
PayloadTemplateSyntaxError,
)
from skyvern.forge.sdk.workflow.models._jinja import _JSON_TYPE_MARKER
from skyvern.forge.sdk.workflow.models.block import (
_JSON_TYPE_MARKER,
FailedToFormatJinjaStyleParameter,
WorkflowTriggerBlock,
jinja_sandbox_env,
@ -323,7 +323,7 @@ class TestCheckTriggerDepth:
block = _make_block()
mock_run = MagicMock()
mock_run.parent_workflow_run_id = None
with patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app:
with patch("skyvern.forge.sdk.workflow.models.misc_blocks.app") as mock_app:
mock_app.DATABASE.workflow_runs.get_workflow_run = AsyncMock(return_value=mock_run)
depth = await block._check_trigger_depth("wr_current")
assert depth == 0
@ -336,7 +336,7 @@ class TestCheckTriggerDepth:
run_no_parent = MagicMock()
run_no_parent.parent_workflow_run_id = None
with patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app:
with patch("skyvern.forge.sdk.workflow.models.misc_blocks.app") as mock_app:
mock_app.DATABASE.workflow_runs.get_workflow_run = AsyncMock(side_effect=[run_with_parent, run_no_parent])
depth = await block._check_trigger_depth("wr_current")
assert depth == 1
@ -350,7 +350,7 @@ class TestCheckTriggerDepth:
run.parent_workflow_run_id = f"wr_parent_{i}" if i < block.MAX_TRIGGER_DEPTH else None
runs.append(run)
with patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app:
with patch("skyvern.forge.sdk.workflow.models.misc_blocks.app") as mock_app:
mock_app.DATABASE.workflow_runs.get_workflow_run = AsyncMock(side_effect=runs)
with pytest.raises(InvalidWorkflowDefinition, match="depth exceeds maximum"):
await block._check_trigger_depth("wr_current")
@ -364,7 +364,7 @@ class TestCheckTriggerDepth:
run.parent_workflow_run_id = f"wr_parent_{i}" if i < block.MAX_TRIGGER_DEPTH - 1 else None
runs.append(run)
with patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app:
with patch("skyvern.forge.sdk.workflow.models.misc_blocks.app") as mock_app:
mock_app.DATABASE.workflow_runs.get_workflow_run = AsyncMock(side_effect=runs)
depth = await block._check_trigger_depth("wr_current")
assert depth == block.MAX_TRIGGER_DEPTH - 1
@ -372,7 +372,7 @@ class TestCheckTriggerDepth:
@pytest.mark.asyncio
async def test_run_not_found_returns_zero(self) -> None:
block = _make_block()
with patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app:
with patch("skyvern.forge.sdk.workflow.models.misc_blocks.app") as mock_app:
mock_app.DATABASE.workflow_runs.get_workflow_run = AsyncMock(return_value=None)
depth = await block._check_trigger_depth("wr_nonexistent")
assert depth == 0
@ -437,7 +437,7 @@ async def test_sync_trigger_preserves_parent_feature_flag_summary(monkeypatch: p
monkeypatch.setattr(WorkflowTriggerBlock, "build_block_result", AsyncMock(return_value=MagicMock()))
try:
with patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app:
with patch("skyvern.forge.sdk.workflow.models.misc_blocks.app") as mock_app:
mock_app.DATABASE.organizations.get_organization = AsyncMock(return_value=organization)
mock_app.WORKFLOW_SERVICE.setup_workflow_run = AsyncMock(side_effect=_setup_workflow_run)
mock_app.WORKFLOW_SERVICE.execute_workflow = AsyncMock(side_effect=_execute_workflow)