mirror of
https://github.com/Skyvern-AI/skyvern.git
synced 2026-07-09 16:09:13 +00:00
Split block.py 8/8: extract control-flow blocks → models/control_flow_blocks.py
Part 8/8 (final). ForLoopBlock, WhileLoopBlock, ConditionalBlock + LoopBlockExecutedResult / compute_conditional_scopes move to control_flow_blocks.py. block.py is now a 495-line facade: block_base re-export + submodule facade imports + BlockSubclasses union + BlockTypeVar + dispatch (get_all_blocks, resolve_conditional_merge_edges) + shared helpers only. Fixes a pydantic forward-ref regression: block.py injects BlockTypeVar into control_flow_blocks and rebuilds ForLoop/WhileLoop after the discriminated union is complete (they type loop_blocks as list[BlockTypeVar]); otherwise WorkflowDefinition.model_rebuild() fails. Block-type test patch targets repointed to their owning modules now that block.py is stripped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c4c208265c
commit
1b80dcc716
17 changed files with 2355 additions and 2306 deletions
File diff suppressed because it is too large
Load diff
2238
skyvern/forge/sdk/workflow/models/control_flow_blocks.py
Normal file
2238
skyvern/forge/sdk/workflow/models/control_flow_blocks.py
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -79,7 +79,6 @@ def _install_context(monkeypatch: pytest.MonkeyPatch, values: dict[str, Any]) ->
|
|||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
monkeypatch.setattr("skyvern.forge.sdk.workflow.models.pdf_fill_block.app", mock_app)
|
||||
monkeypatch.setattr("skyvern.forge.sdk.workflow.models.block.app", mock_app)
|
||||
monkeypatch.setattr("skyvern.forge.sdk.workflow.models.block_base.app", mock_app)
|
||||
return context
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class TestDescriptionSkippedOnLoopIterations:
|
|||
block = _make_block()
|
||||
|
||||
with (
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.app") as mock_app,
|
||||
patch.object(TaskBlock, "execute", new_callable=AsyncMock, return_value=_block_result()),
|
||||
patch.object(Block, "_generate_workflow_run_block_description", new_callable=AsyncMock) as mock_gen_desc,
|
||||
):
|
||||
|
|
@ -80,7 +80,7 @@ class TestDescriptionSkippedOnLoopIterations:
|
|||
block = _make_block()
|
||||
|
||||
with (
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.app") as mock_app,
|
||||
patch.object(TaskBlock, "execute", new_callable=AsyncMock, return_value=_block_result()),
|
||||
patch.object(Block, "_generate_workflow_run_block_description", new_callable=AsyncMock) as mock_gen_desc,
|
||||
):
|
||||
|
|
@ -96,7 +96,7 @@ class TestDescriptionSkippedOnLoopIterations:
|
|||
block = _make_block()
|
||||
|
||||
with (
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.app") as mock_app,
|
||||
patch.object(TaskBlock, "execute", new_callable=AsyncMock, return_value=_block_result()),
|
||||
patch.object(Block, "_generate_workflow_run_block_description", new_callable=AsyncMock) as mock_gen_desc,
|
||||
):
|
||||
|
|
@ -112,7 +112,7 @@ class TestDescriptionSkippedOnLoopIterations:
|
|||
block = _make_block()
|
||||
|
||||
with (
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.app") as mock_app,
|
||||
patch.object(TaskBlock, "execute", new_callable=AsyncMock, return_value=_block_result()),
|
||||
patch.object(Block, "_generate_workflow_run_block_description", new_callable=AsyncMock) as mock_gen_desc,
|
||||
):
|
||||
|
|
|
|||
|
|
@ -124,8 +124,7 @@ async def test_baseline_captured_when_loop_internal_state_is_none():
|
|||
mock_storage.get_downloaded_files = AsyncMock(return_value=[file1])
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.STORAGE = mock_storage
|
||||
await capture_block_download_baseline(context, "org_1", "wr_test", "block_1")
|
||||
|
|
@ -153,8 +152,7 @@ async def test_baseline_recaptured_when_set_by_previous_block():
|
|||
mock_storage.get_downloaded_files = AsyncMock(return_value=[file1, file2])
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.STORAGE = mock_storage
|
||||
await capture_block_download_baseline(context, "org_1", "wr_test", "block_2")
|
||||
|
|
@ -183,8 +181,7 @@ async def test_baseline_recaptured_even_when_loop_set_it():
|
|||
)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.STORAGE = mock_storage
|
||||
await capture_block_download_baseline(context, "org_1", "wr_test", "block_2")
|
||||
|
|
@ -203,8 +200,7 @@ async def test_baseline_capture_degrades_on_timeout():
|
|||
mock_storage.get_downloaded_files = AsyncMock(side_effect=asyncio.TimeoutError)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.STORAGE = mock_storage
|
||||
# Must not raise
|
||||
|
|
@ -225,8 +221,7 @@ async def test_stale_loop_baseline_overwritten_by_fresh_capture():
|
|||
mock_storage.get_downloaded_files = AsyncMock(return_value=[])
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.STORAGE = mock_storage
|
||||
await capture_block_download_baseline(context, "org_1", "wr_test", "block_1")
|
||||
|
|
@ -244,8 +239,7 @@ async def test_baseline_capture_degrades_on_generic_exception():
|
|||
mock_storage.get_downloaded_files = AsyncMock(side_effect=RuntimeError("S3 blip"))
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.STORAGE = mock_storage
|
||||
# Must not raise — baseline capture is best-effort
|
||||
|
|
@ -317,8 +311,7 @@ async def test_sibling_download_blocks_in_loop_iteration_scope_to_own_files():
|
|||
|
||||
async def run_download_block(produced: FileInfo) -> list[FileInfo]:
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.STORAGE = mock_storage
|
||||
await capture_block_download_baseline(context, "org_1", "wr_test", "print")
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ 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 code_block as code_block_module
|
||||
from skyvern.forge.sdk.workflow.models.block import CodeBlock
|
||||
|
|
@ -103,7 +102,6 @@ def _fake_storage_app(monkeypatch: pytest.MonkeyPatch, *, save, get) -> None:
|
|||
execute_code_block_override=AsyncMock(return_value=None),
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(block_module, "app", fake_app)
|
||||
monkeypatch.setattr(block_base_module, "app", fake_app)
|
||||
monkeypatch.setattr(code_block_module, "app", fake_app)
|
||||
|
||||
|
|
@ -222,7 +220,7 @@ async def test_code_block_scopes_downloads_to_current_loop_iteration(
|
|||
run_id="wr_1",
|
||||
loop_internal_state={
|
||||
"downloaded_file_signatures_before_iteration": [
|
||||
block_module.to_downloaded_file_signature(prev_file),
|
||||
block_base_module.to_downloaded_file_signature(prev_file),
|
||||
],
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ from skyvern.forge.sdk.workflow.models.parameter import OutputParameter, Paramet
|
|||
from skyvern.forge.sdk.workflow.service import WorkflowService
|
||||
from skyvern.webeye.browser_artifacts import BrowserArtifacts, VideoArtifact
|
||||
|
||||
_BLOCK_PATH = "skyvern.forge.sdk.workflow.models.block.app"
|
||||
_BLOCK_PATH = "skyvern.forge.sdk.workflow.models.code_block.app"
|
||||
_MANAGER_PATH = "skyvern.forge.sdk.artifact.manager.app"
|
||||
_SERVICE_PATH = "skyvern.forge.sdk.workflow.service.app"
|
||||
|
||||
|
|
|
|||
|
|
@ -762,7 +762,7 @@ async def wrapper({default_args}):
|
|||
return None
|
||||
|
||||
monkeypatch.setattr(
|
||||
"skyvern.forge.sdk.workflow.models.block.app.AGENT_FUNCTION.validate_code_block",
|
||||
"skyvern.forge.sdk.workflow.models.code_block.app.AGENT_FUNCTION.validate_code_block",
|
||||
validate_code_block,
|
||||
)
|
||||
monkeypatch.setattr(CodeBlock, "get_or_create_browser_state", get_browser_state)
|
||||
|
|
@ -986,7 +986,7 @@ class _FakeWorkflowRun:
|
|||
|
||||
def _patch_context_resolution(monkeypatch: "pytest.MonkeyPatch", wrc) -> None:
|
||||
monkeypatch.setattr(
|
||||
"skyvern.forge.sdk.workflow.models.block.app.WORKFLOW_CONTEXT_MANAGER.get_workflow_run_context",
|
||||
"skyvern.forge.sdk.workflow.models.code_block.app.WORKFLOW_CONTEXT_MANAGER.get_workflow_run_context",
|
||||
lambda *args, **kwargs: wrc,
|
||||
)
|
||||
|
||||
|
|
@ -1024,7 +1024,7 @@ async def _run_credential_code_block(monkeypatch: "pytest.MonkeyPatch", wrc, cod
|
|||
persisted["value"] = value
|
||||
|
||||
monkeypatch.setattr(
|
||||
"skyvern.forge.sdk.workflow.models.block.app.AGENT_FUNCTION.validate_code_block",
|
||||
"skyvern.forge.sdk.workflow.models.code_block.app.AGENT_FUNCTION.validate_code_block",
|
||||
validate_code_block,
|
||||
)
|
||||
monkeypatch.setattr(CodeBlock, "get_or_create_browser_state", get_browser_state)
|
||||
|
|
|
|||
|
|
@ -320,8 +320,7 @@ async def test_block_adoption_seam_rebinds_to_run_dir() -> None:
|
|||
browser_state.browser_context.browser = browser
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.PERSISTENT_SESSIONS_MANAGER.get_browser_state = AsyncMock(return_value=browser_state)
|
||||
mock_app.BROWSER_MANAGER.get_or_create_for_workflow_run = AsyncMock()
|
||||
|
|
@ -350,8 +349,7 @@ async def test_block_adoption_seam_rebinds_via_context_page_without_owning_brows
|
|||
browser_state.get_working_page = AsyncMock(return_value=page)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.PERSISTENT_SESSIONS_MANAGER.get_browser_state = AsyncMock(return_value=browser_state)
|
||||
|
||||
|
|
@ -376,8 +374,7 @@ async def test_block_adoption_seam_no_browser_no_page_returns_state() -> None:
|
|||
browser_state.get_working_page = AsyncMock(return_value=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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.PERSISTENT_SESSIONS_MANAGER.get_browser_state = AsyncMock(return_value=browser_state)
|
||||
|
||||
|
|
@ -401,8 +398,7 @@ async def test_block_non_adoption_cache_hit_rebinds_to_run_dir() -> None:
|
|||
browser_state.is_connected = MagicMock(return_value=True)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.BROWSER_MANAGER.get_for_workflow_run = MagicMock(return_value=browser_state)
|
||||
|
||||
|
|
@ -430,8 +426,7 @@ async def test_block_non_adoption_rebinds_when_org_id_missing() -> None:
|
|||
browser_state.is_connected = MagicMock(return_value=True)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.BROWSER_MANAGER.get_for_workflow_run = MagicMock(return_value=browser_state)
|
||||
|
||||
|
|
@ -459,8 +454,7 @@ async def test_block_non_adoption_rebinds_via_context_page_when_browser_is_none(
|
|||
browser_state.get_working_page = AsyncMock(return_value=page)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.BROWSER_MANAGER.get_for_workflow_run = MagicMock(return_value=browser_state)
|
||||
|
||||
|
|
@ -489,9 +483,8 @@ async def test_block_non_adoption_fresh_create_empty_context_rebinds_with_workfl
|
|||
empty_ctx = SkyvernContext(run_id=None, workflow_run_id=None, task_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.block.skyvern_context.current", return_value=empty_ctx),
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.skyvern_context.current", return_value=empty_ctx),
|
||||
):
|
||||
mock_app.BROWSER_MANAGER.get_for_workflow_run = MagicMock(return_value=None)
|
||||
mock_app.WORKFLOW_SERVICE.get_workflow_run = AsyncMock(return_value=MagicMock())
|
||||
|
|
@ -518,8 +511,7 @@ async def test_block_non_adoption_rebind_fail_open() -> None:
|
|||
browser_state.is_connected = MagicMock(return_value=True)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
patch(
|
||||
"skyvern.forge.sdk.workflow.models.block_base.rebind_download_dir",
|
||||
new_callable=AsyncMock,
|
||||
|
|
@ -546,8 +538,7 @@ async def test_block_adoption_seam_fail_open_on_rebind_error() -> None:
|
|||
browser_state.browser_context.browser = MagicMock()
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
patch(
|
||||
"skyvern.forge.sdk.workflow.models.block_base.rebind_download_dir",
|
||||
new_callable=AsyncMock,
|
||||
|
|
@ -595,9 +586,8 @@ async def test_block_adoption_prefers_context_run_id_over_workflow_run_id() -> N
|
|||
ctx = SkyvernContext(run_id="run_ctx", workflow_run_id="wr_block")
|
||||
|
||||
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.block.skyvern_context.current", return_value=ctx),
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.skyvern_context.current", return_value=ctx),
|
||||
):
|
||||
mock_app.PERSISTENT_SESSIONS_MANAGER.get_browser_state = AsyncMock(return_value=browser_state)
|
||||
mock_app.BROWSER_MANAGER.get_or_create_for_workflow_run = AsyncMock()
|
||||
|
|
@ -1108,9 +1098,8 @@ async def test_block_non_adoption_override_takes_precedence_over_context() -> No
|
|||
ctx = SkyvernContext(run_id=None, workflow_run_id="wr_block", task_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.block.skyvern_context.current", return_value=ctx),
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block_base.skyvern_context.current", return_value=ctx),
|
||||
):
|
||||
mock_app.BROWSER_MANAGER.get_for_workflow_run = MagicMock(return_value=browser_state)
|
||||
|
||||
|
|
@ -1136,8 +1125,7 @@ async def test_block_non_adoption_reused_browser_rebinds_to_second_run() -> None
|
|||
browser_state.is_connected = MagicMock(return_value=True)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
):
|
||||
mock_app.BROWSER_MANAGER.get_for_workflow_run = MagicMock(return_value=browser_state)
|
||||
|
||||
|
|
@ -1167,8 +1155,7 @@ async def test_register_downloaded_files_uses_download_run_id_as_storage_key() -
|
|||
block = CodeBlock.__new__(CodeBlock)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.code_block.app", mock_app),
|
||||
):
|
||||
mock_app.STORAGE.save_downloaded_files = AsyncMock()
|
||||
|
|
@ -1192,8 +1179,7 @@ async def test_register_downloaded_files_defaults_to_workflow_run_id() -> None:
|
|||
block = CodeBlock.__new__(CodeBlock)
|
||||
|
||||
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.block_base.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.code_block.app", mock_app),
|
||||
):
|
||||
mock_app.STORAGE.save_downloaded_files = AsyncMock()
|
||||
|
|
@ -1215,7 +1201,7 @@ async def test_register_pdf_uses_download_run_id_as_storage_key() -> None:
|
|||
block = PrintPageBlock.__new__(PrintPageBlock)
|
||||
|
||||
with (
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.misc_blocks.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),
|
||||
):
|
||||
|
|
@ -1240,7 +1226,7 @@ async def test_register_pdf_defaults_to_workflow_run_id() -> None:
|
|||
block = PrintPageBlock.__new__(PrintPageBlock)
|
||||
|
||||
with (
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.misc_blocks.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),
|
||||
):
|
||||
|
|
@ -1312,7 +1298,7 @@ async def test_print_page_block_threads_resolved_id_to_all_sinks(tmp_path) -> No
|
|||
),
|
||||
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.misc_blocks.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),
|
||||
):
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from skyvern.forge.sdk.workflow.models.block import Block, ForLoopBlock, LoopBlo
|
|||
from skyvern.forge.sdk.workflow.models.parameter import OutputParameter
|
||||
from skyvern.schemas.workflows import BlockResult, BlockStatus
|
||||
|
||||
INTERVAL_PATCH = "skyvern.forge.sdk.workflow.models.block.PERSIST_LOOP_OUTPUT_INTERVAL"
|
||||
INTERVAL_PATCH = "skyvern.forge.sdk.workflow.models.control_flow_blocks.PERSIST_LOOP_OUTPUT_INTERVAL"
|
||||
|
||||
|
||||
def _make_output_param(label: str) -> OutputParameter:
|
||||
|
|
@ -71,7 +71,7 @@ class TestExecuteCallsRecordOnceAtEnd:
|
|||
patch.object(ForLoopBlock, "execute_loop_helper", new_callable=AsyncMock, return_value=loop_result),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock) as mock_record,
|
||||
patch.object(Block, "build_block_result", new_callable=AsyncMock, return_value=final_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
):
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
|
||||
|
|
@ -116,8 +116,8 @@ class TestExecuteLoopHelperPersistsToDbDirectly:
|
|||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch.object(ForLoopBlock, "get_loop_block_context_parameters", return_value=[]),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock) as mock_record,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = mock_db_upsert
|
||||
|
|
@ -166,8 +166,8 @@ class TestExecuteLoopHelperPersistsToDbDirectly:
|
|||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch.object(ForLoopBlock, "get_loop_block_context_parameters", return_value=[]),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = mock_db_upsert
|
||||
|
|
@ -207,8 +207,8 @@ class TestExecuteLoopHelperPersistsToDbDirectly:
|
|||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch.object(ForLoopBlock, "get_loop_block_context_parameters", return_value=[]),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = mock_db_upsert
|
||||
|
|
@ -252,8 +252,8 @@ class TestIncrementalPersistFailureResilience:
|
|||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch.object(ForLoopBlock, "get_loop_block_context_parameters", return_value=[]),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = mock_db_upsert
|
||||
|
|
@ -305,8 +305,8 @@ class TestIncrementalPersistFailureResilience:
|
|||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch.object(ForLoopBlock, "get_loop_block_context_parameters", return_value=[]),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = mock_db_upsert
|
||||
|
|
@ -356,8 +356,8 @@ class TestPersistIntervalBatching:
|
|||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch.object(ForLoopBlock, "get_loop_block_context_parameters", return_value=[]),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = mock_db_upsert
|
||||
|
|
@ -389,7 +389,7 @@ class TestPersistIntervalBatching:
|
|||
|
||||
mock_db_upsert = AsyncMock()
|
||||
|
||||
with patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app:
|
||||
with patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app:
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = mock_db_upsert
|
||||
|
||||
await loop_block._persist_partial_loop_output(
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ class TestForLoopParentNextLoopOnFailureSwallowsLastIterationFailure:
|
|||
),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch.object(Block, "build_block_result", side_effect=fake_build_block_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
):
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
await loop_block.execute(
|
||||
|
|
@ -196,7 +196,7 @@ class TestForLoopParentNextLoopOnFailureSwallowsLastIterationFailure:
|
|||
),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch.object(Block, "build_block_result", side_effect=fake_build_block_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
):
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
await loop_block.execute(
|
||||
|
|
@ -252,7 +252,7 @@ class TestForLoopInnerNextLoopOnFailureSwallowsLastIterationFailure:
|
|||
),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch.object(Block, "build_block_result", side_effect=fake_build_block_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
):
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
await loop_block.execute(
|
||||
|
|
@ -307,7 +307,7 @@ class TestForLoopWithoutFlagsStillTerminatesOnBodyFailure:
|
|||
),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch.object(Block, "build_block_result", side_effect=fake_build_block_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
):
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
await loop_block.execute(
|
||||
|
|
@ -363,7 +363,7 @@ class TestWhileLoopParentNextLoopOnFailureSwallowsLastIterationFailure:
|
|||
),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch.object(Block, "build_block_result", side_effect=fake_build_block_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
):
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
await loop_block.execute(
|
||||
|
|
@ -421,7 +421,7 @@ class TestLoopBlockSwallowPathClearsFailureReason:
|
|||
),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch.object(Block, "build_block_result", side_effect=fake_build_block_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
):
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
await loop_block.execute(
|
||||
|
|
@ -473,7 +473,7 @@ class TestLoopBlockSwallowPathClearsFailureReason:
|
|||
),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch.object(Block, "build_block_result", side_effect=fake_build_block_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
):
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
await loop_block.execute(
|
||||
|
|
@ -543,7 +543,7 @@ class TestSyntheticSafetyLimitNotSwallowedByNextLoopOnFailure:
|
|||
),
|
||||
patch.object(Block, "record_output_parameter_value", new_callable=AsyncMock),
|
||||
patch.object(Block, "build_block_result", side_effect=fake_build_block_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
):
|
||||
mock_app.DATABASE.observer.update_workflow_run_block = AsyncMock()
|
||||
await loop_block.execute(
|
||||
|
|
|
|||
|
|
@ -240,8 +240,8 @@ class TestExecuteTopOfLoopSemantics:
|
|||
with (
|
||||
patch.object(WhileLoopBlock, "_evaluate_condition", new_callable=AsyncMock, return_value=False),
|
||||
patch.object(Block, "execute_safe", new_callable=AsyncMock) as mock_execute_safe,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -277,8 +277,8 @@ class TestExecuteTopOfLoopSemantics:
|
|||
with (
|
||||
patch.object(WhileLoopBlock, "_evaluate_condition", new=fake_eval),
|
||||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -328,8 +328,8 @@ class TestExecuteTopOfLoopSemantics:
|
|||
with (
|
||||
patch.object(WhileLoopBlock, "_evaluate_condition", new=fake_eval),
|
||||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -371,11 +371,11 @@ class TestExecuteMaxIterationsCap:
|
|||
|
||||
# Patch the cap to a small number so the test is fast.
|
||||
with (
|
||||
patch("skyvern.forge.sdk.workflow.models.block.DEFAULT_MAX_LOOP_ITERATIONS", 5),
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.DEFAULT_MAX_LOOP_ITERATIONS", 5),
|
||||
patch.object(WhileLoopBlock, "_evaluate_condition", new_callable=AsyncMock, return_value=True),
|
||||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -418,11 +418,11 @@ class TestExecuteMaxIterationsCap:
|
|||
return next(condition_results)
|
||||
|
||||
with (
|
||||
patch("skyvern.forge.sdk.workflow.models.block.DEFAULT_MAX_LOOP_ITERATIONS", 3),
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.DEFAULT_MAX_LOOP_ITERATIONS", 3),
|
||||
patch.object(WhileLoopBlock, "_evaluate_condition", new=fake_eval),
|
||||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -472,8 +472,8 @@ class TestCurrentIndexWrittenBeforeCondition:
|
|||
|
||||
with (
|
||||
patch.object(WhileLoopBlock, "_evaluate_condition", new=fake_eval),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -513,8 +513,8 @@ class TestWhileLoopJinjaCurrentIndexIntegration:
|
|||
|
||||
with (
|
||||
patch.object(Block, "execute_safe", new_callable=AsyncMock) as mock_execute_safe,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -541,8 +541,8 @@ class TestWhileLoopJinjaCurrentIndexIntegration:
|
|||
|
||||
with (
|
||||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result) as mock_execute_safe,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -571,8 +571,8 @@ class TestWhileLoopJinjaCurrentIndexIntegration:
|
|||
|
||||
with (
|
||||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=inner_result) as mock_execute_safe,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -600,8 +600,8 @@ class TestExecuteConditionRenderingErrors:
|
|||
|
||||
with (
|
||||
patch.object(WhileLoopBlock, "_evaluate_condition", new=raise_format_error),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -628,8 +628,8 @@ class TestExecuteConditionRenderingErrors:
|
|||
|
||||
with (
|
||||
patch.object(WhileLoopBlock, "_evaluate_condition", new=raise_missing),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -666,8 +666,8 @@ class TestExecuteCancellationPropagation:
|
|||
with (
|
||||
patch.object(WhileLoopBlock, "_evaluate_condition", new_callable=AsyncMock, return_value=True),
|
||||
patch.object(Block, "execute_safe", new_callable=AsyncMock, return_value=canceled_result),
|
||||
patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.block.skyvern_context") as mock_skyvern_ctx,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app,
|
||||
patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.skyvern_context") as mock_skyvern_ctx,
|
||||
):
|
||||
mock_skyvern_ctx.current.return_value = None
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
|
|
@ -703,7 +703,7 @@ class TestPromptCriteriaEvaluation:
|
|||
mock_context = MagicMock()
|
||||
|
||||
with patch(
|
||||
"skyvern.forge.sdk.workflow.models.block._evaluate_prompt_branch_conditions_batch",
|
||||
"skyvern.forge.sdk.workflow.models.control_flow_blocks._evaluate_prompt_branch_conditions_batch",
|
||||
new_callable=AsyncMock,
|
||||
) as mock_batch:
|
||||
mock_batch.return_value = ([True], ["dates on the page are still recent"], "goal", {})
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ async def test_persist_partial_while_loop_output_calls_db() -> None:
|
|||
loop_blocks=[inner],
|
||||
condition=JinjaBranchCriteria(expression="{{ false }}"),
|
||||
)
|
||||
with patch("skyvern.forge.sdk.workflow.models.block.app") as mock_app:
|
||||
with patch("skyvern.forge.sdk.workflow.models.control_flow_blocks.app") as mock_app:
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter = AsyncMock()
|
||||
await loop._persist_partial_loop_output("wr1", [[]], loop_idx=0)
|
||||
mock_app.DATABASE.workflow_runs.create_or_update_workflow_run_output_parameter.assert_awaited_once()
|
||||
|
|
|
|||
|
|
@ -423,7 +423,7 @@ def _patch_execute_environment(
|
|||
"update_step": AsyncMock(return_value=None),
|
||||
}
|
||||
monkeypatch.setattr(
|
||||
"skyvern.forge.sdk.workflow.models.block.app.AGENT_FUNCTION.validate_code_block", validate_code_block
|
||||
"skyvern.forge.sdk.workflow.models.code_block.app.AGENT_FUNCTION.validate_code_block", validate_code_block
|
||||
)
|
||||
monkeypatch.setattr(CodeBlock, "get_or_create_browser_state", get_browser_state)
|
||||
monkeypatch.setattr(CodeBlock, "get_workflow_run_context", lambda *args: context)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
|||
|
||||
import pytest
|
||||
|
||||
import skyvern.forge.sdk.workflow.models.block as block_module
|
||||
import skyvern.forge.sdk.workflow.models.block_base as block_module
|
||||
from skyvern.exceptions import ConditionalBranchEvaluationError
|
||||
from skyvern.forge.prompts import prompt_engine
|
||||
from skyvern.forge.sdk.workflow.models.block import (
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ from skyvern.forge.sdk.core import skyvern_context
|
|||
from skyvern.forge.sdk.core.skyvern_context import SkyvernContext
|
||||
from skyvern.forge.sdk.experimentation import providers as providers_module
|
||||
from skyvern.forge.sdk.workflow.exceptions import (
|
||||
FailedToFormatJinjaStyleParameter,
|
||||
InvalidWorkflowDefinition,
|
||||
PayloadTemplateRenderError,
|
||||
PayloadTemplateSyntaxError,
|
||||
)
|
||||
from skyvern.forge.sdk.workflow.models._jinja import _JSON_TYPE_MARKER
|
||||
from skyvern.forge.sdk.workflow.models.block import (
|
||||
FailedToFormatJinjaStyleParameter,
|
||||
WorkflowTriggerBlock,
|
||||
jinja_sandbox_env,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ class TestFileParserBlock:
|
|||
with patch.object(object.__getattribute__(app, "_inst"), "LLM_API_HANDLER") as mock_llm:
|
||||
mock_llm.return_value = mock_response
|
||||
|
||||
with patch("skyvern.forge.sdk.workflow.models.block.prompt_engine.load_prompt") as mock_prompt:
|
||||
with patch("skyvern.forge.sdk.workflow.models.parser_blocks.prompt_engine.load_prompt") as mock_prompt:
|
||||
mock_prompt.return_value = "mocked prompt"
|
||||
|
||||
result = await file_parser_block._extract_with_ai([{"name": "John"}, {"name": "Jane"}], MagicMock())
|
||||
|
|
@ -201,7 +201,7 @@ class TestFileParserBlock:
|
|||
with patch.object(object.__getattribute__(app, "_inst"), "LLM_API_HANDLER") as mock_llm:
|
||||
mock_llm.return_value = mock_response
|
||||
|
||||
with patch("skyvern.forge.sdk.workflow.models.block.prompt_engine.load_prompt") as mock_prompt:
|
||||
with patch("skyvern.forge.sdk.workflow.models.parser_blocks.prompt_engine.load_prompt") as mock_prompt:
|
||||
mock_prompt.return_value = "mocked prompt"
|
||||
|
||||
result = await file_parser_block._extract_with_ai("Some text content", MagicMock())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue